c - UART blocks on read -
i have problem uart read (on raspberry pi). works ok stops in loop , waits on data... made option o_ndelay
stops so.
i use 2 terminal windows:
- one used uart program
on second write:
echo '123445' > /dev/ttyama0
(raspberry pi uart port)
complete code below.
#include <stdio.h> #include <unistd.h> //used uart #include <fcntl.h> //used uart #include <termios.h> //used uart int main(int argv, char * argc[]) { // setting uart //------------------------- //----- setup usart 0 ----- //------------------------- //at bootup, pins 8 , 10 set uart0_txd, uart0_rxd (ie alt0 function) respectively int uart0_filestream = -1; //open uart //the flags (defined in fcntl.h): // access modes (use 1 of these): // o_rdonly - open reading only. // o_rdwr - open reading , writing. // o_wronly - open writing only. // // o_ndelay / o_nonblock (same function) - enables nonblocking mode. when set read requests on file can return failure status // if there no input available (instead of blocking). likewise, write requests can return // failure status if output can't written immediately. // // o_noctty - when set , path identifies terminal device, open() shall not cause terminal device become controlling terminal process. uart0_filestream = open("/dev/ttyama0", o_rdwr | o_noctty | o_ndelay); //open in non blocking read/write mode if (uart0_filestream == -1) { //error - can't open serial port printf("error - unable open uart. ensure not in use application\n"); } //configure uart //the flags (defined in termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html): // baud rate:- b1200, b2400, b4800, b9600, b19200, b38400, b57600, b115200, b230400, b460800, b500000, b576000, b921600, b1000000, b1152000, b1500000, b2000000, b2500000, b3000000, b3500000, b4000000 // csize:- cs5, cs6, cs7, cs8 // clocal - ignore modem status lines // cread - enable receiver // ignpar = ignore characters parity errors // icrnl - map cr nl on input // parenb - parity enable // parodd - odd parity (else even) struct termios cfg; //get existing configuration setup tcgetattr(uart0_filestream, &cfg); //fcntl(devicefd, f_setfl, fndelay); fcntl(uart0_filestream, f_setfl, 0); ////set both incoming , outgoing baud rates... cfsetispeed(&cfg, b115200); cfsetospeed(&cfg, b115200); cfg.c_cflag |= (clocal | cread); ////8n1 (8 data bits, no parity, 1 stop bit) cfg.c_cflag &= ~parenb; cfg.c_cflag &= ~cstopb; cfg.c_cflag &= ~csize; cfg.c_cflag |= cs8; cfg.c_cflag &= ~crtscts; //~cnew_rtscts; //disable hardware flow control //use raw unbuffered data mode (eg, not canonical mode) cfg.c_lflag &= ~(icanon | echo | echoe | isig | ignbrk); cfg.c_iflag &= ~(ignpar | ixon | ixoff | ixany); //raw (unprocessed) output mode cfg.c_oflag &= ~opost; tcsetattr(uart0_filestream, tcsanow, &cfg); //transmitting bytes //----- tx bytes ----- unsigned char tx_buffer[20]; unsigned char *p_tx_buffer; p_tx_buffer = &tx_buffer[0]; *p_tx_buffer++ = 'h'; *p_tx_buffer++ = 'e'; *p_tx_buffer++ = 'l'; *p_tx_buffer++ = 'l'; *p_tx_buffer++ = 'o'; if (uart0_filestream != -1) { int count = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0])); //filestream, bytes write, number of bytes write if (count < 0) { printf("uart tx error\n"); } } //receiving bytes //----- check rx bytes ----- while(1) { printf("loop\n"); if (uart0_filestream != -1) { // read 255 characters port if there unsigned char rx_buffer[256]; int rx_length = read(uart0_filestream, (void*)rx_buffer, 255); //filestream, buffer store in, number of bytes read (max) if (rx_length < 0) { //an error occured printf("uart rx error\n"); } else if (rx_length == 0) { //no data waiting printf("no data uart rx test commit\n"); } else { //bytes received rx_buffer[rx_length] = '\0'; printf("%i bytes read : %s\n", rx_length, rx_buffer); //break; } } sleep(1); } //closing uart if no longer needed //----- close uart ----- close(uart0_filestream); return 0; }
i used have same problem, , problem not related code , solution disable login on serial port, there file @ /etc/inittab open file nano , find line:
t0:23:respawn:/sbin/getty -l ttyama0 115200 vt100
and put # char @ begining line save , reboot , working weirdly.
Comments
Post a Comment