Runtime, Queries and Native Workers
Architecture of the STM32 runtime, query paths and native workers.
The standard runtime
The runtime supports up to 16 instance slots. The default configuration provides three independent functional paths.
Master path – LIN1
Host
↓
Slot 0 master_tx_query
↓
Slot 2 master_native
↓
LIN1
↓
Slot 1 master_rx_query
↓
Host
master_native executes the LIN operations on LIN1.
Slave path – LIN2
Host
↓
Slot 3 slave_tx_query
↓
Slot 5 slave_native
↓
LIN2
↓
Slot 4 slave_rx_query
↓
Host
slave_native uses the same generic LIN worker as the master path, but selects LIN2 as its physical channel.
Logging path
Host
↓
Slot 6 logging_tx_query
↓
Slot 8 logging_native
↓
Slot 7 logging_rx_query
↓
Host
Slots 9 through 15 are unused in the default configuration and available for custom runtime applications.
Which source file belongs to which layer?
The runtime architecture maps directly to the repository:
Linux application
|
| host/beiis_lin/client.py
v
beiis-lind
|
| host/beiis_lin/daemon.py
| host/beiis_lin/socket_protocol.py
v
I²C + GPIO6
|
| host/beiis_lin/i2c_transport.py
| host/beiis_lin/gpio_irq.py
v
Runtime dispatcher
|
| stm32/boards/BEIIS_LIN_HAT/frozen/beiis_runtime.py
v
Query
|
| stm32/micropython/apps/query.py
v
Native worker
|
| stm32/micropython/apps/lin_native.py
v
MicroPython binding
|
| stm32/micropython/modules/lin/modlin.c
v
Native LIN functions
|
| stm32/lib/lin/lin.c
| stm32/lib/lin/lin.h
v
Board-specific hardware integration
|
| stm32/boards/BEIIS_LIN_HAT/board_init.c
v
LIN1 / LIN2
This also makes it clear where an extension should be implemented:
New Linux application -> host/ or custom application
New query/application logic -> stm32/micropython/apps/
New MicroPython function -> stm32/micropython/modules/
New time-critical LIN code -> stm32/lib/lin/
New hardware integration -> board_init.c
What does a query do?
A query is a small reusable transport building block.
TX query Host -> Worker
RX query Worker -> Host
A query does not interpret the LIN protocol. It transports payload and channel information to the configured worker or back to the host.
The same query components can therefore be reused by different applications.
What does a native worker do?
Both master_native and slave_native use lin_native.py.
The worker translates runtime messages into calls to the native LIN module.
Operations are grouped by purpose:
Connection and configuration
0x00 PING Check worker
0x01 INIT Set LIN baud rate
Master
0x02 SEND Transmit complete master frame
0x03 REQUEST Request slave response
Slave
0x04 SLAVE_SET Configure slave response
0x05 SLAVE_CLEAR Clear slave response
0x08 SLAVE_RX_SET Configure slave reception
0x09 SLAVE_RX_RECV Retrieve received data
Diagnostics
0x06 LEDS_GET
0x07 LEDS_SET
Request and reply
Request:
Byte 0 Operation
Byte 1.. Operation-specific data
Reply:
Byte 0 Operation
Byte 1 Status
Byte 2.. Result or error text
Status values:
0 OK
1 Invalid request
2 LIN/native error
3 Internal worker error
Higher application layers with custom workers
The standard workers are deliberately generic. They expose individual LIN operations.
A custom worker can instead implement a complete application layer.
For example:
C or Python application
|
| "Set sensor value to 42"
v
TX query
|
v
Custom sensor worker
|
| Generates required LIN frames
| Maintains state
| Reacts to bus events
v
RX query
|
| "Sensor value accepted"
v
C or Python application
The host application no longer has to issue every SEND or REQUEST operation individually.
Interrupt to the Raspberry Pi
The interrupt is not a property of the query itself.
The microcontroller has a general-purpose host interrupt line from PC6 to Raspberry Pi GPIO6.
It signals when host-relevant data are available. beiis-lind waits for that interrupt and then fetches data over I²C.
Thus, higher runtime layers can report events to a C or Python application without requiring that application to poll GPIO or I²C.
Communication between instances
Runtime applications receive a context object called ctx.
source, channel, payload = await ctx.recv()
await ctx.send_host(channel, payload)
ctx.send_to("other_instance", payload, channel)
ctx.publish(channel, payload)
This allows multiple workers to cooperate locally on the microcontroller.
Resources
An instance may reserve hardware resources, for example:
lin1
lin2
The runtime prevents two running instances from owning the same declared resource simultaneously.
Basic and advanced use
The runtime supports both approaches:
Direct LIN control
Host -> Query -> lin_native -> LIN
Custom application layer
Host -> Query -> custom worker -> native functions -> LIN
Simple access remains available while more complex protocols can progressively move onto the microcontroller.