setjmp/longjmp

Has anyone attempted to implement setjmp and longjmp on the FRC?

I certainly wouldn’t want to go there. Having calls to setjmp/longjmp could really complicate debugging of problems, and if you don’t do it just right you could really create a tough problem to solve. It’d just be way too easy to have a dead robot on the field if it wasn’t just right.

What were you thinking of using it for? Perhaps we can come up with a better solution.

I want to use them to implement coroutines. The state machines in camera.c and camera_menu.c can get rather cumbersome if something needs to be added, for example submenus. With setjmp and longjmp it is possible to allocate a bit of stack to each “process” and write such a program straight rather than with states and a switch statement. Each process would give up the cpu at appropriate points (roughly corresponding to the end of each state’s processing in the FSM) by calling a give-up function, and on the next cycle each process is resumed for its next section using longjmp. I did this once on a VAX, and it worked fairly well, but how to do it is not readily apparent on the FRC. (The VAX C runtime’s setjmp and longjmp did not let me tinker with the stack pointer, so I had to write my own setjmp and longjmp functions).

Generally speaking, labels and goto’s (the C equivalent) are strongly discouraged. They complicate code and remove structure that belongs in if’s, while’s, and for’s. Only use this if you absolutely must and all other solutions are totally unacceptable. (And even then, I would stick to the other solutions.)

As for your problem specifically, the state machines are long but the individual sections are short, and all the code is well commented. There’s no other way to do those, really. They’re long processes with lots of steps. (This is for both camera.c and camera_menu.c) The only other way I can think of to do it would be to implement each step as a function and have a function pointer indicate the current step, but that has its own issues (eg, How do you check valid values?).

Also remember that since the processor is not multithreaded, so there is no “giving up” the CPU.

If you don’t like the switch(), you could use the preprocessor to create “more friendly” syntax.

Oooo, I just learned about semi and full coroutines in my concurrency class. That WOULD work nicely for the camera instead of the statemachine. But I imagine you’d be spending most of your time debugging your implementation rather than actually working on robotics code.

Also remember that since the processor is not multithreaded, so there is no “giving up” the CPU.

A context switch simply involves saving all the current registers in the CPU to memory, loading all the saved registers from another thread into it, and letting it run from there. You don’t need any special features in the CPU to do it. Coroutines would be implementable, since they don’t really even involve concurrency. You just jump to another stack, execute for a bit, then yield back.

You don’t need any special features in the CPU to do it.

Ummm, actually you do. You really need to have access to the call (program address) stack. Many of the smaller implementations of the PIC architecture don’t have program access to the call stack.

There are several commericially available RTOS packages available (PICOS, FreeRTOS, Salvo, Pumpkin, …) for the PIC that support multi-tasks and some type of round-robin or priority task scheduling. The practical maximum for many of these implementations are 8-12 tasks. The context save area for the task needs to be about 100 bytes for call stack and hardware registers (like PROD, TAB*, FSR, …) and data sections (.tmpdata, MATH_DATA). In addition, at least a small argument stack is required, so another chunk of memory - say a small 32 byte stack, plus local variable storage. This already puts a task memory structure up over 1/2 of a ram bank in size. This is easy to do, yes, but the costs in terms of chewing up the limited resources on-chip are fairly high.

Ah, my operating systems course fails me again :(. Who would’ve known that learning things on a poorly-simulated CPU rather than on hardware would have given me misconceptions? :smiley:

Thanks for the info, makes me want to go back to my hardware classes again.

Edit: Just read the wikipedia article. Embedded CPUs are crazy.