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.