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,
Piotr