[arch/linux] uart: fix crash if device is wrong

if the serial port can't be openend (e.g. because the device is wrong/doesn't exist), set the reg_addr to NULL and properly check that everywhere

should close #1296
This commit is contained in:
Felix Ruess
2015-08-12 14:13:00 +02:00
parent 6a712d24cd
commit 5aef745ee2
+76 -44
View File
@@ -76,112 +76,140 @@ static void *uart_thread(void *data __attribute__((unused)))
/* add used fds */ /* add used fds */
int fd; int fd;
#if USE_UART0 #if USE_UART0
fd = ((struct SerialPort *)uart0.reg_addr)->fd; if (uart0.reg_addr != NULL) {
FD_SET(fd, &fds_master); fd = ((struct SerialPort *)uart0.reg_addr)->fd;
if (fd > fdmax) { FD_SET(fd, &fds_master);
fdmax =fd; if (fd > fdmax) {
fdmax =fd;
}
} }
#endif #endif
#if USE_UART1 #if USE_UART1
fd = ((struct SerialPort *)uart1.reg_addr)->fd; if (uart1.reg_addr != NULL) {
FD_SET(fd, &fds_master); fd = ((struct SerialPort *)uart1.reg_addr)->fd;
if (fd > fdmax) { FD_SET(fd, &fds_master);
fdmax =fd; if (fd > fdmax) {
fdmax =fd;
}
} }
#endif #endif
#if USE_UART2 #if USE_UART2
fd = ((struct SerialPort *)uart2.reg_addr)->fd; if (uart2.reg_addr != NULL) {
FD_SET(fd, &fds_master); fd = ((struct SerialPort *)uart2.reg_addr)->fd;
if (fd > fdmax) { FD_SET(fd, &fds_master);
fdmax =fd; if (fd > fdmax) {
fdmax =fd;
}
} }
#endif #endif
#if USE_UART3 #if USE_UART3
fd = ((struct SerialPort *)uart3.reg_addr)->fd; if (uart3.reg_addr != NULL) {
FD_SET(fd, &fds_master); fd = ((struct SerialPort *)uart3.reg_addr)->fd;
if (fd > fdmax) { FD_SET(fd, &fds_master);
fdmax =fd; if (fd > fdmax) {
fdmax =fd;
}
} }
#endif #endif
#if USE_UART4 #if USE_UART4
fd = ((struct SerialPort *)uart4.reg_addr)->fd; if (uart4.reg_addr != NULL) {
FD_SET(fd, &fds_master); fd = ((struct SerialPort *)uart4.reg_addr)->fd;
if (fd > fdmax) { FD_SET(fd, &fds_master);
fdmax =fd; if (fd > fdmax) {
fdmax =fd;
}
} }
#endif #endif
#if USE_UART5 #if USE_UART5
fd = ((struct SerialPort *)uart5.reg_addr)->fd; if (uart5.reg_addr != NULL) {
FD_SET(fd, &fds_master); fd = ((struct SerialPort *)uart5.reg_addr)->fd;
if (fd > fdmax) { FD_SET(fd, &fds_master);
fdmax =fd; if (fd > fdmax) {
fdmax =fd;
}
} }
#endif #endif
#if USE_UART6 #if USE_UART6
fd = ((struct SerialPort *)uart6.reg_addr)->fd; if (uart6.reg_addr != NULL) {
FD_SET(fd, &fds_master); fd = ((struct SerialPort *)uart6.reg_addr)->fd;
if (fd > fdmax) { FD_SET(fd, &fds_master);
fdmax =fd; if (fd > fdmax) {
fdmax =fd;
}
} }
}
#endif #endif
/* fds to be read, modified after each select */ /* fds to be read, modified after each select */
fd_set fds; fd_set fds;
while (1) { while (1) {
/* reset list of fds to check */ /* reset list of fds to check */
fds = fds_master; fds = fds_master;
if (select(fdmax + 1, &fds, NULL, NULL, NULL) < 0) { if (select(fdmax + 1, &fds, NULL, NULL, NULL) < 0) {
fprintf(stderr, "uart_thread: select failed!"); fprintf(stderr, "uart_thread: select failed!");
} }
else { else {
#if USE_UART0 #if USE_UART0
if (uart0.reg_addr != NULL) {
fd = ((struct SerialPort *)uart0.reg_addr)->fd; fd = ((struct SerialPort *)uart0.reg_addr)->fd;
if (FD_ISSET(fd, &fds)) { if (FD_ISSET(fd, &fds)) {
uart_receive_handler(&uart0); uart_receive_handler(&uart0);
} }
}
#endif #endif
#if USE_UART1 #if USE_UART1
if (uart1.reg_addr != NULL) {
fd = ((struct SerialPort *)uart1.reg_addr)->fd; fd = ((struct SerialPort *)uart1.reg_addr)->fd;
if (FD_ISSET(fd, &fds)) { if (FD_ISSET(fd, &fds)) {
uart_receive_handler(&uart1); uart_receive_handler(&uart1);
} }
}
#endif #endif
#if USE_UART2 #if USE_UART2
if (uart2.reg_addr != NULL) {
fd = ((struct SerialPort *)uart2.reg_addr)->fd; fd = ((struct SerialPort *)uart2.reg_addr)->fd;
if (FD_ISSET(fd, &fds)) { if (FD_ISSET(fd, &fds)) {
uart_receive_handler(&uart2); uart_receive_handler(&uart2);
} }
}
#endif #endif
#if USE_UART3 #if USE_UART3
if (uart3.reg_addr != NULL) {
fd = ((struct SerialPort *)uart3.reg_addr)->fd; fd = ((struct SerialPort *)uart3.reg_addr)->fd;
if (FD_ISSET(fd, &fds)) { if (FD_ISSET(fd, &fds)) {
uart_receive_handler(&uart3); uart_receive_handler(&uart3);
} }
}
#endif #endif
#if USE_UART4 #if USE_UART4
if (uart4.reg_addr != NULL) {
fd = ((struct SerialPort *)uart4.reg_addr)->fd; fd = ((struct SerialPort *)uart4.reg_addr)->fd;
if (FD_ISSET(fd, &fds)) { if (FD_ISSET(fd, &fds)) {
uart_receive_handler(&uart4); uart_receive_handler(&uart4);
} }
#endif #endif
#if USE_UART5 #if USE_UART5
fd = ((struct SerialPort *)uart5.reg_addr)->fd; if (uart5.reg_addr != NULL) {
if (FD_ISSET(fd, &fds)) { fd = ((struct SerialPort *)uart5.reg_addr)->fd;
uart_receive_handler(&uart5); if (FD_ISSET(fd, &fds)) {
uart_receive_handler(&uart5);
}
} }
#endif #endif
#if USE_UART6 #if USE_UART6
fd = ((struct SerialPort *)uart6.reg_addr)->fd; if (uart6.reg_addr != NULL) {
if (FD_ISSET(fd, &fds)) { fd = ((struct SerialPort *)uart6.reg_addr)->fd;
uart_receive_handler(&uart6); if (FD_ISSET(fd, &fds)) {
uart_receive_handler(&uart6);
}
} }
#endif #endif
} }
} }
return 0; return 0;
} }
void uart_periph_set_baudrate(struct uart_periph *periph, uint32_t baud) void uart_periph_set_baudrate(struct uart_periph *periph, uint32_t baud)
@@ -206,11 +234,15 @@ void uart_periph_set_baudrate(struct uart_periph *periph, uint32_t baud)
int ret = serial_port_open_raw(port, periph->dev, baud); int ret = serial_port_open_raw(port, periph->dev, baud);
if (ret != 0) { if (ret != 0) {
TRACE("Error opening %s code %d\n", periph->dev, ret); TRACE("Error opening %s code %d\n", periph->dev, ret);
serial_port_free(port);
periph->reg_addr = NULL;
} }
} }
void uart_put_byte(struct uart_periph *periph, uint8_t data) void uart_put_byte(struct uart_periph *periph, uint8_t data)
{ {
if (periph->reg_addr == NULL) { return; } // device not initialized ?
/* write single byte to serial port */ /* write single byte to serial port */
struct SerialPort *port = (struct SerialPort *)(periph->reg_addr); struct SerialPort *port = (struct SerialPort *)(periph->reg_addr);
int ret = write((int)(port->fd), &data, 1); int ret = write((int)(port->fd), &data, 1);