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.

Reply via email to