One of the main responsibilities of the QP Framework is to reliably and safely deliver QP events from various producers to Active Objects. The event delivery is asynchronous, meaning that the producers only post events to Active Objects, but don't wait in-line for the processing of the events. Any part of the system can produce events, not necessarily only the Active Objects. For example, ISRs, device drivers, or legacy code running outside the framework can produce events. On the other hand, only Active Objects can consume QP events, because only Active Objects are guaranteed to have event queues.
Event delivery mechanisms can be broadly classified into the following two categories (see Figure SRS-EDM):
Direct event posting is the simplest mechanism that allows producers to post events directly to the event queue of the recipient Active Object. Figure SRS-EDM illustrates this form of communication as red arrows directly connecting event producers and the consumer Active Objects.
Direct event posting is a "push-style" communication mechanism, in which recipients receive unsolicited events whether they "want" them or not. Direct event posting is well suited for situations where a group of Active Objects, or an Active Object and an ISR, form a subsystem providing a particular service, such as a communication stack, GPS capability, digital camera subsystem in a mobile phone, or the like. This style of event passing requires that the event producers "knows" the recipients and their interests in various events. The "knowledge" that a sender needs is, at a minimum, the handle (e.g., a pointer) to the recipient Active Object.
Direct event posting mechanism might increase the coupling among the components, especially when the recipients of the events are hard-coded inside the event producers. However, one way of reducing the coupling is to allow the recipients to "register" with the producers at runtime (e.g., event producer can store a pointer to the direct consumer of the events). That way the producer does not need to hard-code the recipient(s).
Publish-subscribe event delivery is shown in Figure SRS-EDM as a "software bus" into which Active Objects "plug in" through the specified interface. Active Objects interested in certain events subscribe to one or more event signals by the QP Framework. When an event producer chooses to publish an event, QP Framework delivers the event to all subscribers, which entails event multicasting the event (sometimes incorrectly called broadcasting). Publication requests can originate asynchronously from many sources, not necessarily just from Active Objects. For example, events can be published from interrupts (ISRs), device drivers, or the "naked" threads (in case QP runs on top of a conventional RTOS/OS).
Publish-subscribe is a "pull-style" communication mechanism in which recipients receive only solicited (subscribed) events. The properties of the publish-subscribe model are:
In any event-driven system event delivery is critical for proper function of the entire system. If the underlying event-driven infrastructure does not or cannot guarantee event delivery, the application has to compensate by checking, verifying, and potentially repeating delivery of most events. However, in the single address space of an embedded MCU there is really no reason why event delivery (via shared memory) should fail. Under such circumstances, event delivery mechanism is similar to the basic function call mechanism. In both cases these basic mechanisms can fail if the system does not provide enough resources (event queues and event pools in case of event delivery and stack space in case of function call mechanism). Virtually all systems consider the basic function call mechanism to be guaranteed, which assumes the adequate stack resources (this involves multiple stacks if a traditional RTOS is used). Similarly, event-driven systems running in a single address space can consider the basic event delivery mechanism to be guaranteed, which assumes the adequate event-queue and event-pool sizes. Such event delivery guarantee is the single most powerful feature that drastically simplifies QP Applications.
SRS_QP_EDM_00: QP Framework shall provide direct event posting to Active Object instances based on the FIFO policy |
Description The direct event posting mechanism shall post events to the event queue of the recipient Active Object utilizing the FIFO (First-In-First-Out) policy. Direct event posting with the default FIFO policy shall be available to all possible event producers, such as Active Objects, but also interrupts (ISRs), "device drivers", and "naked" threads of an RTOS (if an RTOS is used to run QP). |
Backward Traceability
|
Forward Traceability (truncated to 2 level(s))
|
SRS_QP_EDM_01: QP Framework shall provide direct event self-posting to Active Object instances based on the LIFO policy |
Description Self-posting means that a given Active Object instance posts event to its own event queue. Such self-posting mechanism shall use the same event queue as the default FIFO policy, but in addition to the default FIFO policy it should provide also the LIFO (Last-In-First-Out) policy. This self-posting with the LIFO policy shall use a distinctly different API than the default direct event posting with the FIFO policy. |
Use case Self-posting of events with the LIFO policy can be useful for recalling events that have been deferred by the Active Object instance. |
Backward Traceability
|
Forward Traceability (truncated to 2 level(s))
|
SRS_QP_EDG_10: QP Framework shall provide event delivery guarantee for the direct event posting mechanism. |
Description The event delivery guarantee shall be implemented with the SSFs based on assertion programming specified in SRS_QP_FDM_00. QP Framework shall detect all conditions that could prevent a posted event from reaching the recipient Active Object (in particular event queue overflow and event-pool depletion for mutable events). In case any such condition occurs, QP Framework shall relinquish control and invoke the custom error handler defined in QP Application (see SRS_QP_FDM_20). That way, QP Application does not need to check whether direct event posting was successful (because continuing execution means that it was). |
Forward Traceability (truncated to 2 level(s)) |
SRS_QP_EDM_50: QP Framework shall provide publish-subscribe event delivery mechanism |
Description Publish-subscribe shall use direct event posting (default, reliable variant based on FIFO policy) as the underlying low-level mechanism to multicast the subscribed events. |
Forward Traceability (truncated to 2 level(s))
|
SRS_QP_EDM_51: The publish-subscribe event delivery mechanism shall be configurable and optional |
Description The QP Application shall initialize and configure the publish-subscribe delivery mechanism by supplying the maximum number of event signals that can be subscribed and a memory buffer to store the subscription information. As a special case, QP Application might choose not to initialize publish-subscribe, in which case the feature shall be inactive and shall not cause any waste of resources (RAM). |
Backward Traceability
|
Use case QP Application initializes the publish-subscribe event delivery for a given maximum number of event signals and provides memory buffer capable of holding that many signals for the maximum allowed number of Active Objects in QP Application (see SRS_QP_AO_01). |
Forward Traceability (truncated to 2 level(s)) |
SRS_QP_EDM_52: QP Framework shall allow Active Object instances to subscribe to a given event signal at run-time. |
Description QP Framework shall provide API for Active Objects to subscribe one event signal at a time. The API shall be callable multiple times by a given Active Object to subscribe to multiple event signals. Event subscription requires initialization of the publish-subscribe feature and attempts to subscribe without prior initialization shall be treated as a programming error. Similarly, subscribing to an already subscribed signal (by the same Active Object) shall be treated as a programming error. |
Backward Traceability
|
Forward Traceability (truncated to 2 level(s))
|
SRS_QP_EDM_53: QP Framework shall allow Active Object instances to unsubscribe from a subscribed event signal at run-time. |
Description QP Framework shall provide API for Active Objects to unsubscribe one event signal at a time. The API shall be callable multiple times by a given Active Object to unsubscribe from multiple event signals. Event un-subscription requires initialization of the publish-subscribe feature and attempts to unsubscribe without prior initialization shall be treated as a programming error. Similarly, unsubscribing from a signal that has not been subscribed shall be treated as a programming error. |
Backward Traceability
|
Forward Traceability (truncated to 2 level(s))
|
SRS_QP_EDM_54: QP Framework shall allow Active Object instances to unsubscribe from all subscribed event signals at run-time. |
Description QP Framework shall provide API for Active Objects to unsubscribe from all event signals at ones. Event un-subscription requires initialization of the publish-subscribe feature and attempts to unsubscribe without prior initialization shall be treated as a programming error. |
Forward Traceability (truncated to 2 level(s))
|
SRS_QP_EDM_55: Event multicasting during publishing shall complete before the processing of the published events. |
Description The purpose of this requirement is to prevent event publishing from creating unexpected event sequences when QP Framework runs on top of a preemptive kernel. As specified in SRS_QP_EDM_50, event multicasting (required when a given event signal is subscribed by multiple Active Objects) uses the default direct event posting mechanism. However, if the priority of the event producer is lower than the priority of the recipient Active Object, direct event posting would normally lead to preemption (before multicasting completes). Such a preemption would then cause the high-priority Active Object to immediately process the published event, which might produce other events. These other events would then appear in the event queues of Active Objects before the originally published event. This would generate a confusing event sequence. |
Backward Traceability
|
Use Case QP Framework can fulfill this requirement by preventing preemption during the event multicasting (only needed when QP Framework runs on top of a preemptive kernel). The preemption should be prevented only for the priorities of Active Objects involved in this particular multicasting. An ideal mechanism for that is selective scheduler locking based on priority ceiling protocol. The priority ceiling shall be set to the highest priority subscriber to a given event. |
Forward Traceability (truncated to 2 level(s))
|
SRS_QA_EDM_60: QP Application shall adequately size all event queues and event pools. |
Description According to the QP Framework memory allocation policy defined in the Software Architecture Specification, the size of event queues and event pools is determined by QP Application, not by QP Framework. Therefore, to achieve event delivery guarantee required in SRS_QP_EDG_10, QP Application must supply adequate sizes for the event queues and event pools. |
Forward Traceability (truncated to 2 level(s)) |
SRS_QP_EDM_61: QP Framework may provide alternative unreliable event posting mechanism without event delivery guarantee |
Description The alterative direct event posting mechanism without event delivery guarantee shall detect that a given event cannot be posted, but QP Framework should pass this information to QP Application instead of entering a fail-safe state. The alterative direct event posting mechanism without event delivery guarantee must use a different API than the default mechanism with delivery guarantee. |
Use Case Event posting without event delivery guarantee is useful for events that the application can afford to occasionally lose and can apply only "best effort" to handle. |
Forward Traceability (truncated to 2 level(s)) |
SRS_QP_EDM_62: The alternative unreliable event posting mechanism shall not interfere with the default reliable event posting |
Description An example of interference between the two event posting mechanisms is exhausting queue capacity by the unreliable event posting, so that the reliable event posting fails. Consequently, the unreliable event posting mechanism should not exhaust the event queue resource completely, but rather leave a specified number of unused queue entries (a safety margin) for the reliable event delivery. |
Use Case When using the unreliable direct event posting mechanism, QP Application shall specify a non-zero safety margin of the event queue to which it posts events that can be lost. The unreliable posting should fail (and convey this failure to QP Application) when the safety margin is reached. That way some space in the queue remains available to the reliable (default) event posting mechanism. |
Backward Traceability
|
Forward Traceability (truncated to 2 level(s)) |
SRS_QP_EDM_64: Mutable event allocation shall be reliable. This requirement also means that QP Application is responsible for adequately sizing all event pools. |
Description "Reliable" event allocation means that QP Framework shall detect if the mutable event cannot be allocated (e.g., due to depletion of an event pool of a given block size). In case allocation fails, QP Framework shall enter a fail-safe state. This reliable event allocation policy shall be the default. |
Use Case The default (reliable) event allocation policy frees QP Application from checking whether event allocation was successful (because continuing execution means that it was). |
Forward Traceability (truncated to 2 level(s)) |
SRS_QP_EDM_65: QP Framework may provide alternative unreliable method of allocating mutable events. |
Description The alterative, unreliable method of allocating mutable events must use a different API than the default reliable event allocation. QP Framework still shall detect that a mutable event cannot be allocated, but the framework should pass this information to QP Application instead of entering a fail-safe state. The unreliable event allocation policy shall be a special case and should be used with caution. |
Use Case Unreliable event allocation is useful for events that the application can afford to occasionally lose and can apply only "best effort" to allocate and deliver. |
Forward Traceability (truncated to 2 level(s)) |
SRS_QP_EDM_66: The alternative unreliable event allocation method shall not interfere with the default reliable event allocation. |
Description The alterative unreliable event allocation must co-exist with the default reliable event allocation. An example of interference between the two event allocation methods is exhausting queue capacity by the unreliable event posting, so that the reliable event posting fails and causes the system to enter fail-safe state. |
Backward Traceability
|
Forward Traceability (truncated to 2 level(s)) |
SRS_QP_EDM_80: All event delivery mechanisms shall be free of concurrency hazards. |
Description "Free of concurrency hazards" means free of such hazards as as race conditions and data races. It also means that QP Framework must ensure that the current event does not change (e.g., is not corrupted or prematurely recycled) throughout all RTC steps it is involved in. |
Forward Traceability (truncated to 2 level(s)) |
SRS_QP_EDM_81: All event delivery mechanism shall be deterministic. |
Description "Deterministic" means that the process of event posting or publishing has a known and constant upper bound of its execution time. In case of event publishing, QP Framework cannot meet this requirement alone because the time of event multicasting depends on the number of subscribers to a given event, so it is not constant. Therefore, QP Application must be designed in such a way that the multicasting time is acceptable. |
Forward Traceability (truncated to 2 level(s)) |