Skip to content

Documentation

Runtime, Queries and Native Workers

Architecture of the STM32 runtime, query paths and native workers.

Runtime, Queries 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.