1

I'm having a small architecture argument with a coworker at the moment. I was hoping some of you could help settle it by strongly suggesting one approach over another.

We have a DSP and Cortex-M3 coupled together with shared memory. The DSP receives requests from the external world and some of these requests are to execute certain wireless test functionality which can only be done on the CM3. The DSP writes to shared memory, then signals the CM3 via an interrupt. The shared memory indicates what the request is along with any necessary data required to perform the request (channel to tune to, register of RF chip to read, etc).

My preference is to generate a unique event ID for each request that can occur in the interrupt. Then before leaving the interrupt pass the event on to the state machine's event queue, which would get handled in the thread devoted to RF activity.

My coworker would instead like to pass a single event ID (generic RF command) to the state machine and have the parsing of the shared memory area occur after receiving this event ID in the state machine. After parsing, then you would know the specific command that you need to act on.

I dislike this approach because you will be doing the parsing of shared memory in whatever state you happen to be in. You can make this a function, but it's still processing that should be state-independent. She doesn't like the idea of parsing shared memory in the interrupt.

Any comments on the better approach? If it helps, we're using the QP framework from Miro Samek for state machine implementation.

EDIT: moved statechart to ftp://hiddenoaks.asuscomm.com/Statechart.bmp

Rich von Lehe
  • 1,362
  • 2
  • 16
  • 38
  • There are far too many possible interactions with the rest of your code to consider. It's possible to imagine horrifying implementations and superb implementations fitting either of your descriptions. – jthill Apr 04 '13 at 19:53
  • @jthill - Is there any way to generate UML diagrams within a StackOverflow post? It seems like a state chart would help a lot. – Rich von Lehe Apr 04 '13 at 20:13
  • 1
    I would agree with your judgement. From my experience, it is better to generate meaningful events as early as possible--ideally right in the interrupts. – Miro Samek Jun 23 '13 at 02:53
  • Keeping interrupt latency low is usually a Good Thing. Doing work in an interrupt handler that could be done elsewhere doesn't seem ideal. Loading from the shared memory will cache-miss, and running parsing will take even more time. If these interrupts are frequent, (or latency outside the interrupt handler matters for some reason), maybe you can trigger a prefetch from the shared memory in the interrupt handler, so it's in flight while the CPU is returning from the interrupt into the state machine which will check the flag. – Peter Cordes Jun 28 '16 at 19:33

1 Answers1

3

Here's a compromise:

  • pass a single event ID (generic RF command) to the state machine from the interrupt
  • create an action_function that "parses" the shared memory and returns a specific command
  • guard RF_EVENT transitions in the statechart with [parser_action_func() == RF_CMD_1] etc.

The statechart code generator should be smart enough to execute parser_action_func() only once per RF_EVENT. (Dunno if QP framework is that smart).

This has the same statechart semantics of your "unique event ID for each request," and avoids parsing the shared memory in the interrupt handler.

ADDENDUM

The difference in the statechart is N transitions labeled

----RF_EVT_CMD_1---->
----RF_EVT_CMD_2---->
       ...
----RF_EVT_CMD_N---->

verus

----RF_EVT[cmd()==CMD_1]---->
----RF_EVT[cmd()==CMD_2]---->
        ...
----RF_EVT[cmd()==CMD_N]---->

where cmd() is the parsing action function.

Doug Currie
  • 40,708
  • 1
  • 95
  • 119
  • I think I understand your suggestion. That would be the correct way to model what my coworker is wanting to do. IMO, a guard that generates more than a couple of transitions tends to look ugly, though. I didn't specify how many RF commands there would be. In our case it will be around ten. – Rich von Lehe Apr 04 '13 at 20:09
  • So in your version, there would be 10 transitions each with a unique event; in my solution, there would be 10 transitions, each with a common event and a unique guard. There are the same number of transitions in each case. – Doug Currie Apr 04 '13 at 20:21
  • If you look above, I've posted a not-quite-complete UML state chart. In the diagram I posted, your approach would have a guard with 5 transitions going out of it. Now that the diagram is drawn and I can see that all commands are basically handled by the WirelessEnabled superstate, I'm less concerned that parsing in the state machine is that much uglier. – Rich von Lehe Apr 04 '13 at 21:54
  • I don't find it uglier; see my addendum. You should add the guard to the events on the transitions; there is no need to make a dispatch state. – Doug Currie Apr 05 '13 at 01:02