Using/misusing k_sem_init()

Piotr MieĊ„kowski <piotr.mienkowski at>

Hi all,

I'm reviewing my new code for Atmel SAM low level Ethernet driver and
there is one place where I have a troubling use of k_sem_init()
function. Very shortly my situation:

As is typically the case Atmel's Ethernet MAC module is using a so
called descriptor list to define a linked list of transmission and
reception buffers. These shared buffers are then used to pass data
between MAC module and low level Ethernet driver.

Let's focus on the transmit path. Assuming we have two transmission
buffers and each buffer can store one full Ethernet frame the Ethernet
driver can send up to two frames to the MAC module but to send a third
frame it has to wait until a free buffer becomes available. This is a
perfect case for using counting semaphores.

During driver initialization phase we would call

k_sem_init(&tx_sem, 2, 2);

to initialize semaphores and then k_sem_take() in transmit thread every
time we send a frame and k_sem_give() in IRQ handler every time the MAC
module has read all the data from the transmit buffer. So far so good.
However, now we can have a situation where the driver (transmit thread)
has sent two frames, stopped on k_sem_take() call when trying to send a
third one and at that moment an unrecoverable transmission error
happens. At this point I would like to reinitialize the descriptor list
and also reinitialize the semaphores, i.e. I would like to call
k_sem_init() while there is a thread waiting for the very semaphore to
become available.

Would that be OK, is there a better solution?

Thanks and regards,

Join to automatically receive all group messages.