I'm implementing a serial transmit driver for a micro that isn't running an RTOS and I have some form of an implementation working but I'd like some advice on it. Just a note, the function "getc" is a bit confusing here because it isn't for received characters but rather is a way for the UART empty ISR to get characters to send out. Here's the pseudocode for my implementation: char txBuffer[BUF_SIZE]; int head; int tail; bool empty; int putc(char c) { if no transmission in progress AND empty is TRUE //don't buffer directly write to transmit register; else { if head == tail AND empty is FALSE // txBuffer full return error; else { empty = FALSE; txBuffer[head++] = c; txBuffer %= BUF_SIZE; } } int getc(void) { if empty == TRUE return error; else { ret_val = txBuffer[tail++]; tail %= BUF_SIZE; if tail == head empty = TRUE; return ret_val; } } I want some advice on where I need some sort of synchronization primitives in this implementation. I am disabling interrupts at several points in both the putc() and getc() functions because both are interruptible. getc() is called from the UART empty ISR so that I can send the next character out for transmission. Any advice on where the critical sections are and any other advice on this implementation? I read somewhere that you can come up with an implementation of a circular buffer that doesn't need synchronization by having one wasted spot in the buffer. How would this be implemented? I don't see how this would eliminate the need for synchronization. I appreciate any help.
Serial driver implementation questions
Started by ●August 6, 2006
Reply by ●August 6, 20062006-08-06
joshc wrote:> I'm implementing a serial transmit driver for a micro that isn't > running an RTOS and I have some form of an implementation working but > I'd like some advice on it. Just a note, the function "getc" is a bitI like to use a buffered_bytes_counter because it allows sanity checks. It should: -never be less than 0 -never be more than BUFSIZE -either be wr_ptr-rd_ptr (if wr_ptr > rd_ptr) BUFSIZE + wr_ptr - rd_ptr (if wr_ptr < rd_ptr) You also need the empty flag to see if the special case of wr_ptr=rd_ptr means the buffer is empty or full. Well, something like this anyway..
Reply by ●August 6, 20062006-08-06
On Sat, 05 Aug 2006 21:02:08 -0700, joshc wrote: I read somewhere that you can come up with an implementation of a> circular buffer that doesn't need synchronization by having one wasted > spot in the buffer. How would this be implemented? I don't see how this > would eliminate the need for synchronization.Single-reader single-writer. Google "single reader+synchronization" or see http://www.audiomulch.com/~rossb/code/lockfree for one reference. ~Dave~