Greg, Thanks for the advice, I’ll have a look at use file_open etc.
Regards, Mark — Mark Stevens mark.stev...@wildernesslabs.co > On 10 May 2024, at 15:55, Gregory Nutt <spudan...@gmail.com> wrote: > > 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.