On 5/9/2024 11:02 PM, Mark Stevens wrote:
Hmmm... the UART device will closed when the kernel thread is killed, right?   
When the device is closed, it is also flushed I believe.  If those two things 
are true, then data loss would be expected, right?
Yes, the UART is closed just before we perform a thread_delete(0).
That would be when the all data is flushed from FIFOs and input buffers and lost.
Data loss is accounted for in the protocol.  We send a known packet to the ESP 
and it then responds to the request.  This happens several times (we try 40 
times).  The logic analyser is showing the traffic between the chips and I have 
manually checked the packets and the data looks good.
I don't know the details of these UART drivers, but typically when the driver is closed all data is lost and the receivers are disabled so that nothing more can be received.
Note that for a UART console, stdin is inherited so that the UART is not closed 
when the kernel thread exits.
The UART is opened at the start of the thread not prior to the thread being 
started.

We are doing the following:

int start_uart_thread()
{
     // Configure the thread properties
     handle = kthread_create(… monitor_thread …);
}

void monitor_thread(…)
{
     int uart = open(….);

     // Setup signalling.

     while (!shutting_down) { read and process data }
close(uart);
    kthread_delete(0);
}

Hmmm... I see that you are using file descriptors within the OS. That is not normally done because it is unsafe; it depends on the context in which the code using the file descriptor operates.  If you code operates on a file descriptor within the OS it could clobber the file descriptors of a different task/kthread.  These standard I/O function should be used only by user space code and never within the OS.

That is one thing that should be fixed:  Use file_open(), file_read() and file_close() instead.  This will correctly avoid use of file descriptors.


In this case is does the inheritance go both ways?   As in if I open the UART 
in the kthread does the parent thread keep it open?

You are using a kernel thread above.  Kernel threads and user pthreads work differently:

 * The kthreads work just like tasks and the parent kernel thread knows
   nothing about the drivers opened by the child kernel thread.  The
   opened driver will persist until it is explicitly closed (as above)
   or until the kthread exists.  It will not be kept open for use by
   the parent.
 * With user pthreads, all file descriptors are shared.  If a pthread
   exits, any file descriptors opened by the pthread persist until they
   are explicitly closed or until the task main thread exits.

The driver may not be closed when the main thread exits either. Reference counting is used.  When the driver is closed the reference count is decremented.  The UART will not actually be disabled until the reference count finally decrements to zero.

So if you want the open file to persist for the parent of the kthread you would need to (1) open the driver on the parent (reference count == 1).  (2) Start the child kthread, and (3) open the driver on the child kthread (reference count == 2).  When the child kthread exits (reference count == 1)

This happens normally through file descriptor inheritance in user tasks, but file descriptors are not used within the kernel.


Reply via email to