From: Chris Stratton on
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
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
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
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
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