UART4 read in pthread not working

Hi,

I have programmed (in C) UART4 read in thread with blocking read, the code as below: I confirmed that the UART receive port does have data through oscilloscope, but somehow there is no data in read( ), the return count always zero ?

The strange thing is if minicom is open on the Uart4, then the read( ) in receive thread started to run as normal. However, the regular file write become weird. The string won’t be able to be written into file ?!

Btw, my BBB version is 3.8.13-bone47

#include<stdio.h>
#include<stdlib.h> // required for fopen, exit()
#include<fcntl.h>
#include<termios.h>
//#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include “readerComm.h”

pthread_t uartRxT , uartTxT;
int file, file2;

int main (int argc, char* argv[])
{
int count;

pthread_attr_t attr;
void *status;
FILE *fdata;

if(argc != 2)
{

printf(“Invalid number of arguments, exiting!”);
return -2;

}

if((file = open("/dev/ttyO4", O_RDWR | O_NOCTTY | O_NDELAY ))< 0)
{
perror(“UART: Failed to open the file”);
return -1;
}

fcntl(file, F_SETFL, 0); // blocking read
struct termios options; //oriopt
tcgetattr(file, &options);
options.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
options.c_iflag = IGNPAR | ICRNL;

options.c_iflag &= ~IGNBRK;
options.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

options.c_cc[VMIN] = 2; // Non Canonical input mode (as we didnt set ICANON for c_lflag)
options.c_cc[VTIME] = 10; // 1 sec timeout

tcflush(file, TCIFLUSH);

tcsetattr(file, TCSANOW, &options);

unsigned char cmd[] = {0x11, 0x00, 0x32}; //"Tx From Beaglebone ";

if ((count = write(file, (char*)cmd, 3))<0){
perror(“Failed to write to the output\n”);
return -1;
}else{
printf(“Byte sent: %d \n”, count);
}

fdata = fopen(“capture.dat”, “w”);
if (fdata == NULL) {
printf(“I couldn’t open capture.dat for writing.\n”);
exit(0);
}

// save in file ( cannot print to file ??)
fprintf(fdata, “%s”, “test”);
perror(“UART: Test comment”);

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&
attr, PTHREAD_CREATE_JOINABLE);

// Create UArt Tx thread
if(pthread_create(&uartTxT, &attr, &uartTxWait, NULL)){
perror(“GPIO: Failed to create the tx thread”);

return -1;
}

// Create Uart Rx thread
if(pthread_create(&uartRxT, &attr, &uartRxWait, NULL)){
perror(“GPIO: Failed to create the rx thread”);

return -1;
}

pthread_attr_destroy(&attr);
pthread_join(uartRxT,&status);
pthread_join(uartTxT,&status);

close(file); // close first file descriptor

// capture.dat file close
fclose(fdata);

return 0;

}

// UART RX thread
void* uartRxWait(void *param){

unsigned char receive[100];
int count, n;
fd_set input;
struct timeval timeout;

//initialize input set
FD_ZERO(&input);
FD_SET(file, &input);

timeout.tv_sec=0;
timeout.tv_usec=0;

while(1){

if ((count = read(file, (void *)receive, 100))<0)
{
perror(“Failed to read from input \n”);
printf(“count = %d\n”, count);
}else{

if(receive[2]==0x32){
printf(“Header received \n”);
}
printf(“Byte received [%d] \n”, count);
printf(“Value of Pi = 0x%.2x\n”, receive[0]);

}

}

pthread_exit(0);
}

void* uartTxWait(void *param){

usleep(1000000);
pthread_exit(0);
}

Serial interface initialisation on Linux systems is a mess and it is easy to forget something. That’s why I would recommend to use a library which does all the work for you like liboapc from https://sourceforge.net/p/oapc/code/ci/master/tree/liboapc/

Hi Karl,

Thanks for suggestion.

My problem in the code seems to be more specific to pthread, because if I have the read( ) in a while loop, then the UART receive is running normally. Data arrived at the receive buffer are able to be pick up. However, the problem begin when I create UART Rx thread that just continuously reading the UART buffer.

Regina

Try adding fflush(stdout) and fflush(stderr) as the last statements in your while loop so you can see the outputs while the thread is running.

You thread code looks funky, main() launches the threads and then immediately drops into phtread_join to wait for the Rx thread to terminate, which doesn’t look like it’ll happen without killing the program. Or have you left out some of your code?

Another potential problem is that it looks like you send the command in main before launching the thread to receive the reply.

Hi Wally,

I have tried adding fflush(stdout and fflush(stderr) in the while loop, however, in the UartRxWait thread, the read( ) function is in block waiting for incoming data. Which doesn’t output anything. In the case, after start and shut down minicom, the UartRxWait thread running as usual, there is no output from the fflush(stdout) and fflush(stderr) either.

yes, at the moment I have to kill the program to terminate. I have modified the code such that it loop for only 5 times and terminate the thread.

// UART RX thread
void* uartRxWait(void *param){

unsigned char receive[100];
int count;
static int n;

while(n<5){
if ((count = read(file, (void *)receive, 100))<0)
{
perror(“Failed to read from input \n”);
printf(“count = %d\n”, count);
}else{

if(receive[2]==0x32){
printf(“Header received \n”);
}
printf(“Byte received [%d] \n”, count);
printf(“Value of Pi = 0x%.2x\n”, receive[0]);
}
n++;
fflush(stdout);
fflush(stderr);
}

pthread_exit(0);
}

One thing I observed is that, my regular file write is able to write something: I don’t understand why?

fdata = fopen(“capture.dat”, “w”);
if (fdata == NULL) {
printf(“I couldn’t open capture.dat for writing.\n”);
exit(0);
}
// save in file
fprintf(fdata, “%s”, “test”);

Yes, I send the command before launching the thread to receive the reply. I thought it doesn’t matter as the receive byte will be stored in buffer. Anyway, I tried placing the sending command after receive thread, but the problem still exist.

I noticed you have options.c_cc[VMIN] = 2; If for some reason only one character comes in, it’ll block forever. Try using options.c_cc[VMIN] = 0; so that each char can timeout if its not received.

How big are the Beaglebone uart buffers?

You may still have a race between your write of the data and starting your RX thread. Try putting the write into your TX thread and launch it after you’ve launched the RX thread.

Apology for late reply.

I’ve tried with options.c_cc[VMIN] = 0; it’s still the same issue.

From the datasheet of AM335x, uart rx/tx buffers are 64 bytes.

I’ve also tried putting tx command in tx thread that activated later than rx thread. Nothing changed as well.

void* uartTxWait(void *param){

int count;
usleep(1000000);
unsigned char cmd[] = {0x10, 0x00, 0x32}; //"Tx From Beaglebone ";

if ((count = write(file, (char*)cmd, 3))<0){
perror(“Failed to write to the output\n”);
//tcsetattr(file, TCSAFLUSH, &oriopt); //before exit, undo raw setting
//return -1;
}else{
printf(“Byte sent: %d \n”, count);
}

pthread_exit(0);
}

I’m stumped. Are you now getting timeout error messages from the read thread?

Are you getting the Byte sent: message printf from the TX thread?

Thanks for reply.

I’m not sure why, but I don’t get timeout error messages from the read thread (though I have set it to 1 sec) !? It just freeze there waiting for UART input, even though there are UART input coming in.

Yes, I got the Byte sent message printf from TX thread. Please see the attachement.

Screenshot from 2016-07-26 10:46:45.png

Are you sure everything you’re using code wise is thread safe ? There are a lot of library functions that are not thread safe.

I’m not aware of library functions that are not thread safe, can you give some example library function that is not thread safe? So if the library function is not thread safe, what would be the effect if we accidentally use it in our program?

Does that means we cannot use the library function completely in pthread if it is not thread safe and resort to polling mechanism?

If I recall correctly, typically anything that is related to interrupts, and blocking file reads( things of this nature - where you’re waiting ) are not thread safe as these types of calls can be preempted by another thread. So, what I’d do to test if my assumption is correct. Is to write a test app without threading. Or perhaps write a callback, but again, callbacks are definitely not thread safe.

I’m not seeing all the posts in this discussion for some reason. But is there a specific reason why you need threads ? Because if you need this sort of process segregation, it may be best to run entirely different processes( multiple executables ), and then use some form of IPC mechanism such as shared memory. Which POSIX shared memory really is fairly simple once you become familiar with it. I had to do this with an application I wrote several months back ,myself. Since a library I was using used callbacks extensively and was not playing nicely on the stack ( preempting my own code routinely ).

Actually I had tried using the sigaction(SIGIO, &saio, NULL) with signal handler function on UART receive. Still there is no triggering/running on the signal handler function. I believe this is quite similar to the callback function that you mention.

The reason of me using the pthread is that I would like the UART receive to run in asynchronous while my main function can do other stuff, and not polling on UART receive. Anyway, your suggestion of running multiple executables is insightful. I’ve never used that before, any get started material can you recommend?

perhaps this: http://www.ibm.com/developerworks/aix/library/au-spunix_sharedmemory/index.html there is better material out there, but it may take a while to find it. Something I’ll have to do later. But in the meantime you can just google “shm_open()” and read around.

My application on the beaglebone black are multithread and for the reception there is a thread. And I don’t have any problem receiving data on this thread. Don’t forget to use mutex and semaphore.

Yeah, this is not something I’ve personally experienced or tested. Was simply a guess on my behalf. However, I am seeing a lot of code in the groups here lately that over complicates reading, and writing to / from UARTs on the Beaglebone.

For example, this is how simple it is to read from a serial device in Nodejs: https://github.com/wphermans/Bonejs/blob/master/examples/serial-read-example.js

Granted, C is not exactly event driven like javascript. It could be, but essentially it all boils down to polling via a “message pump” ( a loop ).

So basically, all one needs to do is open() on the serial device path, and perform a blocking read(), or write a callback that acts on received data somehow. Both methods have similar issues, at least in the context that this process should be handled, or run all by it’s self.

As far as setting serial device parameters. This can be done via an external cmd line tool such as getty, fgetty, or similar. If it must be dynamic . . . then you could even wrap these same already existent cmd line tools. I think that ideally, a very simple demo app, should be less than 100 lines of code, and very easy to read.

SO yeah, maybe I’ll eventually write up an example in C, and blog on it. But it probably won’t be today.

@Regina,

Here is a discussion I started on the subject last year as I was experimenting with POSIX shared memory. On 43oh.com forums. I have lots of examples here as I was experimenting: http://forum.43oh.com/topic/8686-posix-ipc-shared-memory-mmap/

@Micka

Can you share the snippet of your code that configure the UART? Is it using blocking read on UART? I suspect maybe the problem may have to do with the incorrect configuration, as after start/shutdown minicom, then the UART C program start to run properly.

@ William

Thanks for information, I will have a look at it.

Since you are not getting the timeout errors from your read thread, there is definitely something wrong with your UART initilization. And since you need to kill your program with Ctr-C, your read thread would seem to be running and blocking main() in the pthread_join().

Have you read through this guide:
https://www.cmrr.umn.edu/~strupp/serial.html

While your device is not a modem, odds are you want to talk to it as if it were, but instead of using “AT commands” your device will have its own command-response protocol for your program to implement.

The suggestion to use separate programs communicating by shared memory protected by a named semaphore is viable but should not be necessary. But I often first write a thread function as main() in a stand alone program and move it into a thread function once I’ve got it basically working.