Part of my overall architecture of the serial port is a circular buffer. A circular buffer is nice because it is a pretty well-known construct: you put a bunch of stuff in, you take a bunch of stuff out, and as long as you don't overwrite the buffer, you never have to worry about stack space.
Of course when you have multiple threads accessing the circular buffer, it can get hectic.
I added two things to the circular buffer: a semaphore, and a seek command.
The semaphore works to regulate access to the buffer for the multiple threads. Each circular buffer has its own semaphore, so the accessor functions wait for the semaphore to be released before they can access it, and they release it when they are done. It's a pretty well-known mechanism for multithreaded and multitasking operating systems.
The other feature that I added is a seek, which basically allows you to "look ahead" in a circular buffer without actually taking characters off of it. Part of the functionality that I need in this program is a "read until character" function, which allows you to "sit" on the serial port for some specified time until a character comes in (like a [return]). One of two things should happen: either it sees the character and returns a string, or it times out and returns a timeout message.
Well, I had a bug in my code where when I was testing whether the circular buffer was empty, I was returning before releasing the semaphore. It gets more complex in that I was also setting a timeout value on the semaphore at 5 seconds, so I was actually getting some activity. And it was a bitch to find, but find it I did, and now I have a working serial port that runs from a cold boot.
I think there must be some sort of celebratory thing this weekend.