Zap Execution Contexts

Zap code can execute in several different contexts.

A context refers either to a thread, an IRQ, or an RTOS timer execution context.

A context essentially describes a processor's registers. When one context is swapped for another context, the current context's state (i.e. the processor's registers) is saved and the processor's registers are updated with the new context's previously saved state. Once the processor registers are updated with the new context's state the processor continues executing as if the new context were executing the whole time. In this way multiple independent contexts can exist in ZentriOS.

When in a context, all called functions execute within that context.

However, in one context you can set up an event that is handled in another context when the event takes place.

So, for example, if X is the current context, and functions A thru Z are called, every one of those functions execute in context X.

It's important to note that while executing functions A thru Z, context X could be temporarily suspended, and context Y could begin executing other functions. When context X resumes it continues executing its functions.

Note: By default all Zap code executes in the Zap thread context.

To execute in a different context, specific APIs or flags are required.

For each context below, there are details of the APIs and flags that determine execution in that context.

Context Attributes

A context can be described by the following attributes.

Stack Space

Stack space is the local memory available within the current context. Variables and buffers declared inside a function are considered local and reside 'on the stack'. When a function calls another function, the calling function's local variables are placed on the stack before going into the called function. In this way the stack is implemented as last-in-first-out (LIFO). A context has limited amount of stack space. If a context's stack overflows then hardfaults will likely occur.

Priority

A context has a certain priority in the system. By priority, it is meant the algorithm used to determine which context to execute next. A given context can be 'preempted' by another context with higher priority.

Non-Blocking

Certain contexts must never block. That is, code that executes in a non-blocking context must quickly execute then return. If a context allows for blocking then when a blocking section of code is executed, the blocked context is suspended and another non-blocked context resumes execution.

Initialized

Some contexts are initialized on ZentriOS startup while others are initialized when needed.

Invoked

Contexts are invoked in different ways. Some are event driven while others depend on hardware.

Summary of Context Attributes

The execution contexts in the table below are listed in priority order, with highest priority at the top.

Execution ContextStack SpacePriorityNon-blockingInitializedInvoked
Hardware IRQ 1512IRQ (above Highest)N/AWhen hardware IRQ triggered
RTOS Timer 1512HighestN/AOn RTOS timer time-out
Network Thread6KHighOn ZentriOS startupWhen network event issued
System Event Thread 11KMedium-HighOn ZentriOS startupWhen system event issued
HTTP Server Thread 25KMedium-HighWhen HTTP Server startsWhen HTTP request issued
Zap Thread6KMedium (configurable)When Zap is loadedWhen Zap has event to execute
Command Thread 26KMediumOn ZentriOS startupWhen external command received

1: Resources for these execution contexts are extremely limited. Defer complex processing to a context with more resources.

2: These execution contexts have a system monitor to prevent lock-ups. Limit callback blocking time as specified in context description.

Available Contexts

The following contexts are available to a Zap.

Zap Thread

This is the default ZentriOS Application context. Unless otherwise specified, all Zap code executes within this context.

The following ZentriOS APIs issue events that are added to the Zap thread event queue, or register event handlers to be executed when an event is encountered in the event queue:

Network Thread

This is where ZentriOS network related tasks execute. Zap code will execute in this context using the Event API and the ZOS_EVENT_FLAG_NETWORK_THREAD flag.

Zap code executes in the network thread with the following APIs:

Events execute in the network thread if issued or registered with the ZOS_EVENT_FLAG_NETWORK_THREAD flag using the following APIs:

System Event Thread

This is where simple ZentriOS tasks execute. For instance, this context is where the LEDs are updated.

Events that execute in the system event thread should be very simple and non-blocking.

Events execute in the system event thread if issued or registered with the ZOS_EVENT_FLAG_SYS_EVENT_THREAD flag using the following APIs:

HTTP Server Thread

This is where HTTP server callbacks are executed. Code in this context may block, but no other HTTP server callbacks can execute until the current callback returns.

Zap code executes in the HTTP Server context with the following APIs:

The HTTP Server thread has a system monitor which ensures the serial command processor does not lock up.

HTTP request callbacks, e.g. zn_hs_register_dynamic_page(), must not block for more than 25s.

Command Thread

This is where external commands are executed. While this context may block, no other external commands may execute until the current command completes.

External commands are received from:

Zap code executes in the Command Thread context in response to the following APIs:

The Command Thread has a system monitor which ensures the serial command processor does not lock up. Custom command callbacks must NOT block for more than 30s. If a custom command does need to run longer then zn_cmd_update_system_monitor should periodically be called to update the system monitor before the 30s timeout.

Hardware IRQ

This is where an MCU interrupt vector executes. This has extremely high priority. Code in an IRQ must be extremely simple. Furthermore, an IRQ must never block.

When using an IRQ callback, defer heavy processing to the Zap Thread by using an RTOS object such as:

The Zap Thread should block on the RTOS object and begin executing when the object's state changes.

Another option is to issue an event with a ZOS_EVENT_FLAG_FROM_IRQ flag

Zap code executes in a hardware IRQ context using the following APIs:

RTOS Timer

This is where an RTOS timer callback executes. An RTOS timer callback is very similar to a hardware IRQ callback.

The callback should be extremely simple and never block.

WARNING: An RTOS timer callback runs at a very high priority and has limited stack. RTOS timer callback processing must be very limited. Heavier processing should be done other threads, such as the ZAP or network threads. Running the timer frequently, for example every 1ms, is strongly discouraged as it can lead to instabilities elsewhere in the system.

When using an RTOS timer callback, defer heavy processing to the Zap Thread by using an RTOS object such as:

Zap code executes in a RTOS timer context with the following API: