September 22, 2024
The big picture in JeeH is still not right: I don’t like the way device drivers
run in an exception-centric “handler” mode, whereas the rest of the application
uses “thread” mode. This distinction was needed to provide atomic guards around
certain parts of JeeH’s core data structures. This also affects the app-supplied
lowestPower
and resumePower
functions, used to enter sleep modes “when there
is no work”. It’s a bit odd that we need to be in a special mode when …
idling!
...
June 12, 2024
One of the problems I want to address in JeeH, is how to best interface with
peripherals: built-in as well as connected via a common bus, e.g. I2C or SPI.
There are two sides to this: talking to built-in hardware via device
registers, and talking through built-in hardware to a connected module / chip.
Hardware register access
#
Talking to the built-in hardware is a matter of reading and writing the
hardware registers at specific addresses. This is already solved in JeeH with
the use of IoReg<...>
definitions. To configure the “B” port of the GPIO
hardware in an STM32 for example, JeeH defines a GPIOB
object (a constant type
really) which can be referenced as an array. Here’s how to set its pin 8 high:
...
May 19, 2024
The DMA-based UART driver in JeeH is an interesting example of the interaction
between hardware, memory use, and blocking behaviour.
Reading data
#
In JeeH, the way to read bytes from the UART is to send a message to its device
driver, and wait for its reply. The mTag
field is 'R'
, with the mLen
and
mPtr
field starting off as zero. The driver uses a small ring buffer
internally, which is filled in via DMA as bytes arrive. The CPU is not involved.
...
April 21, 2024
As mentioned in my previous Threads vs Async I/O
musings, threads are no longer the main concurrency mechanism I’m after, tasks
are. Threads are still present in JeeH (and they actually work), but I’m not
so keen on having to allocate stacks for each thread, nor on deciding up front
how large they need to be.
So what is a task?
#
Tasks are a bit different. I’m using the same sys::send
and sys::recv
mechanism for them as threads and device drivers, but they run as part of the
thread which created them. Sending a message to a task behaves as if the
message is sent to its owning thread and then forwarded to that specific task.
...
March 28, 2024
Looks like it’s that time of year again: I’m ripping apart what I have in JeeH
5.3 and reconstructing it in a different way. Perhaps it’s just madness, but I
have two reasons to do this: 1) the task/thread design is too
messy and 2) the way I can add and run tests is too tedious.
Tasks vs threads
#
The first issue was unavoidable, once I figured out that tasks should not be an
add-on to a threaded system, but exactly the other way around: threads are a
special kind of task. Threads are tasks with their own stack, which can
therefore be suspended and resumed. Tasks can’t: they either run to completion
or they act on their “owning thread’s” behalf, i.e. they suspend their thread
with them, if needed. This change puts tasks first, and optionally adds
threads and context switching when needed. Then again, the reality is a bit more
complex: there is in fact always one thread, the main()
app code. It’s just
that there’s no context switching involved until at least a second thread is
created (with sys::fork()
, as before). To support this, JeeH must be given an
extra stack for interrupts, exceptions, and system calls, so that it can use
ARM’s PSP + MSP dual stack approach (as before) and use PendSV for context
switching.
...
March 3, 2024
It was a mistake in JeeH to call something a Task
when it really is a
Thread
, so I’ve decided to rename them everywhere in the code and in the
documentation. Threads are separate execution contexts, each with their own
stack. And that’s what’s in JeeH right now.
Threads
#
Threads are a bit of a double-edged sword: yes, you can nicely modularise
different parts of an application this way, especially in the context of a µC
where lots of external events and interrupts are going on. But on a single-CPU
system (i.e. all but the most extensive ARM Cortex µCs) they still need to run
one at a time. There is no real parallelism going on. The inconvenience of
threads is that each one needs to have its own stack area, each sized to handle
peak memory needs, even though most of it will not be used at the same time. It
can be quite wasteful, especially on a RAM-constrained µC.
...
December 22, 2023
Musings ≠ weblog. The jeelabs.org
site used to be my old weblog. For a
fairly long time I posted there on a daily basis. Lots of topics I wanted to
write about, as I discovered Arduino’s, the whole field of “physical computing”,
and then went on to produce and sell JeeNodes, JeeLinks, JeePlugs, etc. It was
great fun while it lasted, but at some point I ran out of fuel.
...