Skip to content

Commit

Permalink
2.3.0
Browse files Browse the repository at this point in the history
- Added scheduler lock according to SRP
- Corrected blinky_button examples to use time events
  • Loading branch information
quantum-leaps committed Jun 8, 2023
1 parent de45bb8 commit 8774cea
Show file tree
Hide file tree
Showing 47 changed files with 350 additions and 201 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ SST provides the following features:
- preemptive, priority-based scheduling
- multiple tasks per prioriy level
- multiple "activations" per task (event queues)
- selective scheduler locking according to "Stack Resource Policy" (SRP)<br>
(a non-blocking mutual exclusion mechansim for protecting shared resources)

> **NOTE**<br>
The execution profile of SST tasks perfectly matches the non-blocking and
Expand Down
8 changes: 7 additions & 1 deletion include/sst.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#ifndef SST_H_
#define SST_H_

#include <stdint.h> /* standard C99 integer types */
#include <stdint.h> /* standard C99 integers */
#include <stdbool.h> /* standard C99 Boolean */
#include "sst_port.h" /* SST port for specific CPU */

Expand Down Expand Up @@ -90,6 +90,12 @@ int SST_Task_run(void); /* run SST tasks static */
SST_PORT_TASK_OPER
#endif

/* lock the SST task scheduler up to the provided priority ceiling (SRP) */
SST_LockKey SST_Task_lock(SST_TaskPrio ceiling);

/* unlock the SST task scheduler with the provided lock key */
void SST_Task_unlock(SST_LockKey lock_key);

/* SST Time Event facilities -----------------------------------------------*/
/*! SST internal time-event tick counter */
typedef uint16_t SST_TCtr;
Expand Down
3 changes: 3 additions & 0 deletions include/sst.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class Task {
virtual void init(Evt const * const ie) = 0;
virtual void dispatch(Evt const * const e) = 0;

static LockKey lock(TaskPrio ceiling);
static void unlock(LockKey key);

static int run(void);

#ifdef SST_PORT_TASK_OPER
Expand Down
53 changes: 46 additions & 7 deletions sst0_c/examples/blinky/blinky.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@

DBC_MODULE_NAME("blinky") /* for DBC assertions in this module */

/*..........................................................................*/
typedef struct { /* Blinky task */
/* Blinky event-driven task ------------------------------------------------*/
typedef struct {
SST_Task super; /* inherit SST_Task */

SST_TimeEvt te1;
Expand All @@ -45,6 +45,7 @@ static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e);
static Blinky Blinky_inst; /* the Blinky instance */
SST_Task * const AO_Blinky = &Blinky_inst.super; /* opaque AO pointer */

/*..........................................................................*/
void Blinky_instantiate(void) {
Blinky_ctor(&Blinky_inst);
}
Expand All @@ -58,7 +59,13 @@ void Blinky_ctor(Blinky * const me) {
SST_TimeEvt_ctor(&me->te2, TIMEOUT2_SIG, &me->super);
}

/*..........................................................................*/
/* macro to select the Blinky implementation */
#define BLINKY_IMPL 2

/*--------------------------------------------------------------------------*/
#if BLINKY_IMPL == 1
/* Blinky implementation closest matching the traditional blocking approach */

static void Blinky_init(Blinky * const me, SST_Evt const * const ie) {
(void)ie; /* unused parameter */

Expand All @@ -68,18 +75,50 @@ static void Blinky_init(Blinky * const me, SST_Evt const * const ie) {
static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e) {
switch (e->sig) {
case TIMEOUT1_SIG: {
BSP_ledOff();
SST_TimeEvt_arm(&me->te2, BSP_TICKS_PER_SEC*3U/4U, 0U);
BSP_ledOn();
SST_TimeEvt_arm(&me->te2, BSP_TICKS_PER_SEC / 4U, 0U);
break;
}
case TIMEOUT2_SIG: {
BSP_ledOff();
SST_TimeEvt_arm(&me->te1, BSP_TICKS_PER_SEC * 3U/4U, 0U);
break;
}
default: {
DBC_ERROR(200);
break;
}
}
}

/*--------------------------------------------------------------------------*/
#elif BLINKY_IMPL == 2
/* Blinky implementation with two periodic time events with offset */

static void Blinky_init(Blinky * const me, SST_Evt const * const ie) {
(void)ie; /* unused parameter */
SST_TimeEvt_arm(&me->te1, 1U, BSP_TICKS_PER_SEC);
SST_TimeEvt_arm(&me->te2, 1U + (BSP_TICKS_PER_SEC/4U), BSP_TICKS_PER_SEC);
}
/*..........................................................................*/
static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e) {
switch (e->sig) {
case TIMEOUT1_SIG: {
BSP_ledOn();
SST_TimeEvt_arm(&me->te1, BSP_TICKS_PER_SEC/4U, 0U);
break;
}
case TIMEOUT2_SIG: {
BSP_ledOff();
break;
}
default: {
DBC_ERROR(500); /* unexpected event */
DBC_ERROR(200);
break;
}
}
}

/*--------------------------------------------------------------------------*/
#else
#error "Wrong definition of the macro BLINKY_VERSION"
#endif
2 changes: 1 addition & 1 deletion sst0_c/examples/blinky/bsp_nucleo-l053r8.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
void SysTick_Handler(void); /* prototype */

void SysTick_Handler(void) { /* system clock tick ISR */
SST_TimeEvt_tick();
SST_TimeEvt_tick(); /* process all SST time events */
}

/* Assertion handler ======================================================*/
Expand Down
47 changes: 26 additions & 21 deletions sst0_c/examples/blinky_button/blinky1.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*============================================================================
* Super-Simple Tasker (SST/C) Example
* Super-Simple Tasker (SST0/C) Example
*
* Copyright (C) 2006-2023 Quantum Leaps, <state-machine.com>.
*
Expand Down Expand Up @@ -27,60 +27,65 @@
#include "bsp.h" /* Board Support Package interface */
#include "blinky_button.h" /* application shared interface */

DBC_MODULE_NAME("blinky1")
DBC_MODULE_NAME("blinky1") /* for DBC assertions in this module */

/*..........................................................................*/
typedef struct { /* Blinky1 task */
SST_Task super; /* inherit SST_Task */
uint16_t toggles;
uint8_t ticks;
uint8_t tick_ctr;
typedef struct { /* Blinky1 task */
SST_Task super; /* inherit SST_Task */
SST_TimeEvt te; /* time event for generating TIMEOUT events */
uint16_t toggles; /* number of toggles to perform for TIMEOUT event */
} Blinky1;

static void Blinky1_ctor(Blinky1 * const me);
static void Blinky1_init(Blinky1 * const me, SST_Evt const * const ie);
static void Blinky1_dispatch(Blinky1 * const me, SST_Evt const * const e);

/*..........................................................................*/
static Blinky1 Blinky1_inst; /* the Blinky instance */
SST_Task * const AO_Blinky1 = &Blinky1_inst.super; /* opaque AO pointer */

void Blinky1_instantiate(void) {
Blinky1_ctor(&Blinky1_inst);
}

/*..........................................................................*/
void Blinky1_ctor(void) {
Blinky1 * const me = &Blinky1_inst;
static void Blinky1_ctor(Blinky1 * const me) {
SST_Task_ctor(
&me->super,
(SST_Handler)&Blinky1_init,
(SST_Handler)&Blinky1_dispatch);
SST_TimeEvt_ctor(&me->te, TIMEOUT_SIG, &me->super);
}

/*..........................................................................*/
static void Blinky1_init(Blinky1 * const me, SST_Evt const * const ie) {
/* the initial event must be provided and must be WORKLOAD_SIG */
DBC_REQUIRE(300,
(ie != (SST_Evt const *)0) && (ie->sig == BLINKY_WORK_SIG));

SST_TimeEvt_arm(&me->te,
SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks,
SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks);
me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles;
me->ticks = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks;
me->tick_ctr = me->ticks;
}
/*..........................................................................*/
static void Blinky1_dispatch(Blinky1 * const me, SST_Evt const * const e) {
switch (e->sig) {
case TICK_SIG: {
--me->tick_ctr;
if (me->tick_ctr == 0U) {
me->tick_ctr = me->ticks;
for (uint16_t i = me->toggles; i > 0U; --i) {
BSP_d5on();
BSP_d5off();
}
case TIMEOUT_SIG: {
for (uint16_t i = me->toggles; i > 0U; --i) {
/* SST scheduler lock is not needed in non-preemptive SST0 */
//SST_LockKey key = SST_Task_lock(3U);
BSP_d5on();
BSP_d5off();
//SST_Task_unlock(key);
}
break;
}
case BLINKY_WORK_SIG: {
BSP_d5on();
SST_TimeEvt_arm(&me->te,
SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks,
SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks);
me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles;
me->ticks = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks;
BSP_d5off();
break;
}
Expand Down
41 changes: 22 additions & 19 deletions sst0_c/examples/blinky_button/blinky3.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,59 +27,62 @@
#include "bsp.h" /* Board Support Package interface */
#include "blinky_button.h" /* application shared interface */

DBC_MODULE_NAME("blinky3")
DBC_MODULE_NAME("blinky3") /* for DBC assertions in this module */

/*..........................................................................*/
typedef struct { /* Blinky3 task */
SST_Task super; /* inherit SST_Task */
uint16_t toggles;
uint8_t ticks;
uint8_t tick_ctr;
typedef struct { /* Blinky3 task */
SST_Task super; /* inherit SST_Task */
SST_TimeEvt te; /* time event for generating TIMEOUT events */
uint16_t toggles; /* number of toggles to perform for TIMEOUT event */
} Blinky3;

static void Blinky3_ctor(Blinky3 * const me);
static void Blinky3_init(Blinky3 * const me, SST_Evt const * const ie);
static void Blinky3_dispatch(Blinky3 * const me, SST_Evt const * const e);

/*..........................................................................*/
static Blinky3 Blinky3_inst; /* the Blinky3 instance */
SST_Task * const AO_Blinky3 = &Blinky3_inst.super; /* opaque AO pointer */

void Blinky3_instantiate(void) {
Blinky3_ctor(&Blinky3_inst);
}

/*..........................................................................*/
void Blinky3_ctor(void) {
Blinky3 * const me = &Blinky3_inst;
static void Blinky3_ctor(Blinky3 * const me) {
SST_Task_ctor(
&me->super,
(SST_Handler)&Blinky3_init,
(SST_Handler)&Blinky3_dispatch);
SST_TimeEvt_ctor(&me->te, TIMEOUT_SIG, &me->super);
}
/*..........................................................................*/
static void Blinky3_init(Blinky3 * const me, SST_Evt const * const ie) {
/* the initial event must be provided and must be WORKLOAD_SIG */
DBC_REQUIRE(300,
(ie != (SST_Evt const *)0) && (ie->sig == BLINKY_WORK_SIG));

SST_TimeEvt_arm(&me->te,
SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks,
SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks);
me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles;
me->ticks = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks;
me->tick_ctr = me->ticks;
}
/*..........................................................................*/
static void Blinky3_dispatch(Blinky3 * const me, SST_Evt const * const e) {
switch (e->sig) {
case TICK_SIG: {
--me->tick_ctr;
if (me->tick_ctr == 0U) {
me->tick_ctr = me->ticks;
for (uint16_t i = me->toggles; i > 0U; --i) {
BSP_d2on();
BSP_d2off();
}
case TIMEOUT_SIG: {
for (uint16_t i = me->toggles; i > 0U; --i) {
BSP_d2on();
BSP_d2off();
}
break;
}
case BLINKY_WORK_SIG: {
BSP_d2on();
SST_TimeEvt_arm(&me->te,
SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks,
SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks);
me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles;
me->ticks = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks;
BSP_d2off();
break;
}
Expand Down
10 changes: 5 additions & 5 deletions sst0_c/examples/blinky_button/blinky_button.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include "dbc_assert.h" /* Design By Contract (DBC) assertions */

enum Signals {
TICK_SIG,
TIMEOUT_SIG,
BUTTON_PRESSED_SIG,
BUTTON_RELEASED_SIG,
BLINKY_WORK_SIG,
Expand All @@ -50,16 +50,16 @@ typedef struct {
uint16_t toggles; /* number of toggles of the signal */
} ButtonWorkEvt;

void Blinky1_ctor(void);
void Blinky1_instantiate(void);
extern SST_Task * const AO_Blinky1; /* opaque task pointer */

void Blinky3_ctor(void);
void Blinky3_instantiate(void);
extern SST_Task * const AO_Blinky3; /* opaque task pointer */

void Button2a_ctor(void);
void Button2a_instantiate(void);
extern SST_Task * const AO_Button2a; /* opaque task pointer */

void Button2b_ctor(void);
void Button2b_instantiate(void);
extern SST_Task * const AO_Button2b; /* opaque task pointer */

#endif /* BLINKY_BUTTON_H_ */
5 changes: 1 addition & 4 deletions sst0_c/examples/blinky_button/bsp_ek-tm4c123gxl.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,7 @@ void SysTick_Handler(void); /* prototype */
void SysTick_Handler(void) { /* system clock tick ISR */
BSP_d1on();

/* immutable timeout event */
static SST_Evt const tickEvt = { TICK_SIG };
SST_Task_post(AO_Blinky1, &tickEvt); /* every tick is fast for Blinky1 */
SST_Task_post(AO_Blinky3, &tickEvt);
SST_TimeEvt_tick(); /* process all SST time events */

/* Perform the debouncing of buttons. The algorithm for debouncing
* adapted from the book "Embedded Systems Dictionary" by Jack Ganssle
Expand Down
5 changes: 1 addition & 4 deletions sst0_c/examples/blinky_button/bsp_nucleo-c031c6.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ void SysTick_Handler(void); /* prototype */
void SysTick_Handler(void) { /* system clock tick ISR */
BSP_d1on();

/* immutable timeout event */
static SST_Evt const tickEvt = { TICK_SIG };
SST_Task_post(AO_Blinky1, &tickEvt); /* every tick is fast for Blinky1 */
SST_Task_post(AO_Blinky3, &tickEvt);
SST_TimeEvt_tick(); /* process all SST time events */

/* Perform the debouncing of buttons. The algorithm for debouncing
* adapted from the book "Embedded Systems Dictionary" by Jack Ganssle
Expand Down
5 changes: 1 addition & 4 deletions sst0_c/examples/blinky_button/bsp_nucleo-h743zi.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,7 @@ void SysTick_Handler(void); /* prototype */
void SysTick_Handler(void) { /* system clock tick ISR */
BSP_d1on();

/* immutable timeout event */
static SST_Evt const tickEvt = { TICK_SIG };
SST_Task_post(AO_Blinky1, &tickEvt); /* every tick is fast for Blinky1 */
SST_Task_post(AO_Blinky3, &tickEvt);
SST_TimeEvt_tick(); /* process all SST time events */

/* Perform the debouncing of buttons. The algorithm for debouncing
* adapted from the book "Embedded Systems Dictionary" by Jack Ganssle
Expand Down
5 changes: 1 addition & 4 deletions sst0_c/examples/blinky_button/bsp_nucleo-l053r8.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ void SysTick_Handler(void); /* prototype */
void SysTick_Handler(void) { /* system clock tick ISR */
BSP_d1on();

/* immutable timeout event */
static SST_Evt const tickEvt = { TICK_SIG };
SST_Task_post(AO_Blinky1, &tickEvt); /* every tick is fast for Blinky1 */
SST_Task_post(AO_Blinky3, &tickEvt);
SST_TimeEvt_tick(); /* process all SST time events */

/* Perform the debouncing of buttons. The algorithm for debouncing
* adapted from the book "Embedded Systems Dictionary" by Jack Ganssle
Expand Down
Loading

0 comments on commit 8774cea

Please sign in to comment.