From: Chris Stratton on 10 Sep 2009 12:14 On Sep 9, 7:35 pm, "Fevric J. Glandules" <f...(a)invalid.invalid> wrote: > If, for example, incoming commands are ASCII sequences > like "L11" for "LED 1 on" followed by an end-of-message > checksum byte, in pseudo-code, something like this: > > uart_isr() { // push chars into circular buffer > push_char_to_uart_buf() > if (char == end_of_message) message_flag = 1; > } I like this approximate approach, but I think you may find the specific implementation may break if you get complete messages queuing up in the receive buffer while you are handling a time-consuming one - your flag won't show how many, so you may miss the subsequent ones. I'd either change it to a count, or preferably detect the ends of messages when copying to the evaluation buffer. In the latter case, the ISR just becomes a software extensions of whatever tiny (typically 1 to 16 byte) buffer exists in the fifo peripheral.
From: Fevric J. Glandules on 10 Sep 2009 17:06 nospam wrote: > PIC18s are 8 bit processors. So they are. I've spent enough time with the datasheet and looking at example assembler and my own disassembled C code that you'd think it would have percolated back to my consciousness by now. Mind, it was quite late when I wrote that.
From: Fevric J. Glandules on 10 Sep 2009 17:18 Bob wrote: <snip> > Yes, that works fine. I've coded several things, both in-house and > outside products pretty much the way you describe. <snip> Thanks to you and all the other respondents; sounds like I'm not straying too far into thedailywtf.com territory, so far.
From: Fevric J. Glandules on 10 Sep 2009 17:23 Chris Stratton wrote: > On Sep 9, 7:35�pm, "Fevric J. Glandules" <f...(a)invalid.invalid> wrote: >> If, for example, incoming commands are ASCII sequences >> like "L11" for "LED 1 on" followed by an end-of-message >> checksum byte, in pseudo-code, something like this: >> >> uart_isr() { // push chars into circular buffer >> � push_char_to_uart_buf() >> � if (char == end_of_message) message_flag = 1; >> } > > I like this approximate approach, but I think you may find the > specific implementation may break if you get complete messages queuing > up in the receive buffer while you are handling a time-consuming one - > your flag won't show how many, so you may miss the subsequent ones. I'm bearing this in mind - the pseudo-code was as simple as I could make it, in order to make clear the general gist.
From: Tim Wescott on 10 Sep 2009 20:46
On Wed, 09 Sep 2009 23:35:07 +0000, Fevric J. Glandules wrote: > Hi all, > > I am new to this group but checking over recent postings seems to > indicate a fair amount of Clue kicking around [1]. > > A bit of background before y'all tell me to RTFM or JFGI. > > I've got quite a lot of experience in programming 8 bit microcontrollers > with assembler; I've also done quite a lot of 32 bit embedded stuff > using an RTOS with C. What's new to me is using a 16 bit mid-range > PIC18 device in C. > > So I'm trying to make sure that I come up with a fairly sensible > architecture. Googling isn't much help - most of the "tutorial" stuff > out there is aimed at a very low level, or else you find discussion at > the nuts and bolts level of a particular interrupt handler. > > The application is probably fairly typical - inputs / commands come in > via the UART, peripheral devices need to be turned on and off in > response, other devices need to be queried via I2C for data, etc. > > My current thinking is to have a main() loop that is subdivided into > separate sections that deal with each peripheral in turn. > > Each code block will be non-blocking, and will implement a state machine > for each peripheral. Incoming comms will run off interrupts. In RTOS > terms, a sort-of round-robin system. > > If, for example, incoming commands are ASCII sequences like "L11" for > "LED 1 on" followed by an end-of-message checksum byte, in pseudo-code, > something like this: > > uart_isr() { // push chars into circular buffer > push_char_to_uart_buf() > if (char == end_of_message) message_flag = 1; > } > > main_loop { > if (message_flag) { > move_chars_from_uart_buf_to_command_buf() switch (command) { > case foo: foo_state = 1; > case bar: bar_state = 1; > } > } > // foo machine > if (foo_state) { > switch (foo_state) { > case 1: if (foo1()) foo_state = 2; > case 2: if (foo2()) foo_state = 0; > } > // bar machine > if (bar_state) { > switch (bar_state) { > case 1: if (bar1()) bar_state = 2; > case 2: if (bar2()) bar_state = 0; > } > } > > Does that make sense? Should the ISR do as little as possible or is it > a good idea to give it some "awareness"? > > The above pseudo-code is just meant to give an idea of where I'm > heading, so don't take it too seriously. I'm really looking for general > pointers on how to approach a mid-level architecture. > > Oh go on then, rip me to shreds. > > [1] I've also dug out the FAQ. This looked interesting when I first saw it, but I haven't tried it: http://www.embedded.com/columns/technicalinsights/190302110? _requestid=61933. Writing for it will be a lot like the task loop you describe, except that you'll get prioritized tasking. Beware the stack -- the PIC 18xxx parts let you monitor the stack and move things off to RAM when it fills up, but making it work is your job. -- www.wescottdesign.com |