Skip to content

Commit 8774cea

Browse files
committed
2.3.0
- Added scheduler lock according to SRP - Corrected blinky_button examples to use time events
1 parent de45bb8 commit 8774cea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+350
-201
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ SST provides the following features:
2424
- preemptive, priority-based scheduling
2525
- multiple tasks per prioriy level
2626
- multiple "activations" per task (event queues)
27+
- selective scheduler locking according to "Stack Resource Policy" (SRP)<br>
28+
(a non-blocking mutual exclusion mechansim for protecting shared resources)
2729

2830
> **NOTE**<br>
2931
The execution profile of SST tasks perfectly matches the non-blocking and

include/sst.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#ifndef SST_H_
2727
#define SST_H_
2828

29-
#include <stdint.h> /* standard C99 integer types */
29+
#include <stdint.h> /* standard C99 integers */
3030
#include <stdbool.h> /* standard C99 Boolean */
3131
#include "sst_port.h" /* SST port for specific CPU */
3232

@@ -90,6 +90,12 @@ int SST_Task_run(void); /* run SST tasks static */
9090
SST_PORT_TASK_OPER
9191
#endif
9292

93+
/* lock the SST task scheduler up to the provided priority ceiling (SRP) */
94+
SST_LockKey SST_Task_lock(SST_TaskPrio ceiling);
95+
96+
/* unlock the SST task scheduler with the provided lock key */
97+
void SST_Task_unlock(SST_LockKey lock_key);
98+
9399
/* SST Time Event facilities -----------------------------------------------*/
94100
/*! SST internal time-event tick counter */
95101
typedef uint16_t SST_TCtr;

include/sst.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ class Task {
7777
virtual void init(Evt const * const ie) = 0;
7878
virtual void dispatch(Evt const * const e) = 0;
7979

80+
static LockKey lock(TaskPrio ceiling);
81+
static void unlock(LockKey key);
82+
8083
static int run(void);
8184

8285
#ifdef SST_PORT_TASK_OPER

sst0_c/examples/blinky/blinky.c

+46-7
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929

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

32-
/*..........................................................................*/
33-
typedef struct { /* Blinky task */
32+
/* Blinky event-driven task ------------------------------------------------*/
33+
typedef struct {
3434
SST_Task super; /* inherit SST_Task */
3535

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

48+
/*..........................................................................*/
4849
void Blinky_instantiate(void) {
4950
Blinky_ctor(&Blinky_inst);
5051
}
@@ -58,7 +59,13 @@ void Blinky_ctor(Blinky * const me) {
5859
SST_TimeEvt_ctor(&me->te2, TIMEOUT2_SIG, &me->super);
5960
}
6061

61-
/*..........................................................................*/
62+
/* macro to select the Blinky implementation */
63+
#define BLINKY_IMPL 2
64+
65+
/*--------------------------------------------------------------------------*/
66+
#if BLINKY_IMPL == 1
67+
/* Blinky implementation closest matching the traditional blocking approach */
68+
6269
static void Blinky_init(Blinky * const me, SST_Evt const * const ie) {
6370
(void)ie; /* unused parameter */
6471

@@ -68,18 +75,50 @@ static void Blinky_init(Blinky * const me, SST_Evt const * const ie) {
6875
static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e) {
6976
switch (e->sig) {
7077
case TIMEOUT1_SIG: {
71-
BSP_ledOff();
72-
SST_TimeEvt_arm(&me->te2, BSP_TICKS_PER_SEC*3U/4U, 0U);
78+
BSP_ledOn();
79+
SST_TimeEvt_arm(&me->te2, BSP_TICKS_PER_SEC / 4U, 0U);
7380
break;
7481
}
7582
case TIMEOUT2_SIG: {
83+
BSP_ledOff();
84+
SST_TimeEvt_arm(&me->te1, BSP_TICKS_PER_SEC * 3U/4U, 0U);
85+
break;
86+
}
87+
default: {
88+
DBC_ERROR(200);
89+
break;
90+
}
91+
}
92+
}
93+
94+
/*--------------------------------------------------------------------------*/
95+
#elif BLINKY_IMPL == 2
96+
/* Blinky implementation with two periodic time events with offset */
97+
98+
static void Blinky_init(Blinky * const me, SST_Evt const * const ie) {
99+
(void)ie; /* unused parameter */
100+
SST_TimeEvt_arm(&me->te1, 1U, BSP_TICKS_PER_SEC);
101+
SST_TimeEvt_arm(&me->te2, 1U + (BSP_TICKS_PER_SEC/4U), BSP_TICKS_PER_SEC);
102+
}
103+
/*..........................................................................*/
104+
static void Blinky_dispatch(Blinky * const me, SST_Evt const * const e) {
105+
switch (e->sig) {
106+
case TIMEOUT1_SIG: {
76107
BSP_ledOn();
77-
SST_TimeEvt_arm(&me->te1, BSP_TICKS_PER_SEC/4U, 0U);
108+
break;
109+
}
110+
case TIMEOUT2_SIG: {
111+
BSP_ledOff();
78112
break;
79113
}
80114
default: {
81-
DBC_ERROR(500); /* unexpected event */
115+
DBC_ERROR(200);
82116
break;
83117
}
84118
}
85119
}
120+
121+
/*--------------------------------------------------------------------------*/
122+
#else
123+
#error "Wrong definition of the macro BLINKY_VERSION"
124+
#endif

sst0_c/examples/blinky/bsp_nucleo-l053r8.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
void SysTick_Handler(void); /* prototype */
4646

4747
void SysTick_Handler(void) { /* system clock tick ISR */
48-
SST_TimeEvt_tick();
48+
SST_TimeEvt_tick(); /* process all SST time events */
4949
}
5050

5151
/* Assertion handler ======================================================*/

sst0_c/examples/blinky_button/blinky1.c

+26-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*============================================================================
2-
* Super-Simple Tasker (SST/C) Example
2+
* Super-Simple Tasker (SST0/C) Example
33
*
44
* Copyright (C) 2006-2023 Quantum Leaps, <state-machine.com>.
55
*
@@ -27,60 +27,65 @@
2727
#include "bsp.h" /* Board Support Package interface */
2828
#include "blinky_button.h" /* application shared interface */
2929

30-
DBC_MODULE_NAME("blinky1")
30+
DBC_MODULE_NAME("blinky1") /* for DBC assertions in this module */
3131

3232
/*..........................................................................*/
33-
typedef struct { /* Blinky1 task */
34-
SST_Task super; /* inherit SST_Task */
35-
uint16_t toggles;
36-
uint8_t ticks;
37-
uint8_t tick_ctr;
33+
typedef struct { /* Blinky1 task */
34+
SST_Task super; /* inherit SST_Task */
35+
SST_TimeEvt te; /* time event for generating TIMEOUT events */
36+
uint16_t toggles; /* number of toggles to perform for TIMEOUT event */
3837
} Blinky1;
3938

39+
static void Blinky1_ctor(Blinky1 * const me);
4040
static void Blinky1_init(Blinky1 * const me, SST_Evt const * const ie);
4141
static void Blinky1_dispatch(Blinky1 * const me, SST_Evt const * const e);
4242

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

47+
void Blinky1_instantiate(void) {
48+
Blinky1_ctor(&Blinky1_inst);
49+
}
50+
4751
/*..........................................................................*/
48-
void Blinky1_ctor(void) {
49-
Blinky1 * const me = &Blinky1_inst;
52+
static void Blinky1_ctor(Blinky1 * const me) {
5053
SST_Task_ctor(
5154
&me->super,
5255
(SST_Handler)&Blinky1_init,
5356
(SST_Handler)&Blinky1_dispatch);
57+
SST_TimeEvt_ctor(&me->te, TIMEOUT_SIG, &me->super);
5458
}
55-
5659
/*..........................................................................*/
5760
static void Blinky1_init(Blinky1 * const me, SST_Evt const * const ie) {
5861
/* the initial event must be provided and must be WORKLOAD_SIG */
5962
DBC_REQUIRE(300,
6063
(ie != (SST_Evt const *)0) && (ie->sig == BLINKY_WORK_SIG));
6164

65+
SST_TimeEvt_arm(&me->te,
66+
SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks,
67+
SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks);
6268
me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles;
63-
me->ticks = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks;
64-
me->tick_ctr = me->ticks;
6569
}
6670
/*..........................................................................*/
6771
static void Blinky1_dispatch(Blinky1 * const me, SST_Evt const * const e) {
6872
switch (e->sig) {
69-
case TICK_SIG: {
70-
--me->tick_ctr;
71-
if (me->tick_ctr == 0U) {
72-
me->tick_ctr = me->ticks;
73-
for (uint16_t i = me->toggles; i > 0U; --i) {
74-
BSP_d5on();
75-
BSP_d5off();
76-
}
73+
case TIMEOUT_SIG: {
74+
for (uint16_t i = me->toggles; i > 0U; --i) {
75+
/* SST scheduler lock is not needed in non-preemptive SST0 */
76+
//SST_LockKey key = SST_Task_lock(3U);
77+
BSP_d5on();
78+
BSP_d5off();
79+
//SST_Task_unlock(key);
7780
}
7881
break;
7982
}
8083
case BLINKY_WORK_SIG: {
8184
BSP_d5on();
85+
SST_TimeEvt_arm(&me->te,
86+
SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks,
87+
SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks);
8288
me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles;
83-
me->ticks = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks;
8489
BSP_d5off();
8590
break;
8691
}

sst0_c/examples/blinky_button/blinky3.c

+22-19
Original file line numberDiff line numberDiff line change
@@ -27,59 +27,62 @@
2727
#include "bsp.h" /* Board Support Package interface */
2828
#include "blinky_button.h" /* application shared interface */
2929

30-
DBC_MODULE_NAME("blinky3")
30+
DBC_MODULE_NAME("blinky3") /* for DBC assertions in this module */
3131

3232
/*..........................................................................*/
33-
typedef struct { /* Blinky3 task */
34-
SST_Task super; /* inherit SST_Task */
35-
uint16_t toggles;
36-
uint8_t ticks;
37-
uint8_t tick_ctr;
33+
typedef struct { /* Blinky3 task */
34+
SST_Task super; /* inherit SST_Task */
35+
SST_TimeEvt te; /* time event for generating TIMEOUT events */
36+
uint16_t toggles; /* number of toggles to perform for TIMEOUT event */
3837
} Blinky3;
3938

39+
static void Blinky3_ctor(Blinky3 * const me);
4040
static void Blinky3_init(Blinky3 * const me, SST_Evt const * const ie);
4141
static void Blinky3_dispatch(Blinky3 * const me, SST_Evt const * const e);
4242

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

47+
void Blinky3_instantiate(void) {
48+
Blinky3_ctor(&Blinky3_inst);
49+
}
50+
4751
/*..........................................................................*/
48-
void Blinky3_ctor(void) {
49-
Blinky3 * const me = &Blinky3_inst;
52+
static void Blinky3_ctor(Blinky3 * const me) {
5053
SST_Task_ctor(
5154
&me->super,
5255
(SST_Handler)&Blinky3_init,
5356
(SST_Handler)&Blinky3_dispatch);
57+
SST_TimeEvt_ctor(&me->te, TIMEOUT_SIG, &me->super);
5458
}
5559
/*..........................................................................*/
5660
static void Blinky3_init(Blinky3 * const me, SST_Evt const * const ie) {
5761
/* the initial event must be provided and must be WORKLOAD_SIG */
5862
DBC_REQUIRE(300,
5963
(ie != (SST_Evt const *)0) && (ie->sig == BLINKY_WORK_SIG));
6064

65+
SST_TimeEvt_arm(&me->te,
66+
SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks,
67+
SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks);
6168
me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->toggles;
62-
me->ticks = SST_EVT_DOWNCAST(BlinkyWorkEvt, ie)->ticks;
63-
me->tick_ctr = me->ticks;
6469
}
6570
/*..........................................................................*/
6671
static void Blinky3_dispatch(Blinky3 * const me, SST_Evt const * const e) {
6772
switch (e->sig) {
68-
case TICK_SIG: {
69-
--me->tick_ctr;
70-
if (me->tick_ctr == 0U) {
71-
me->tick_ctr = me->ticks;
72-
for (uint16_t i = me->toggles; i > 0U; --i) {
73-
BSP_d2on();
74-
BSP_d2off();
75-
}
73+
case TIMEOUT_SIG: {
74+
for (uint16_t i = me->toggles; i > 0U; --i) {
75+
BSP_d2on();
76+
BSP_d2off();
7677
}
7778
break;
7879
}
7980
case BLINKY_WORK_SIG: {
8081
BSP_d2on();
82+
SST_TimeEvt_arm(&me->te,
83+
SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks,
84+
SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks);
8185
me->toggles = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->toggles;
82-
me->ticks = SST_EVT_DOWNCAST(BlinkyWorkEvt, e)->ticks;
8386
BSP_d2off();
8487
break;
8588
}

sst0_c/examples/blinky_button/blinky_button.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "dbc_assert.h" /* Design By Contract (DBC) assertions */
3030

3131
enum Signals {
32-
TICK_SIG,
32+
TIMEOUT_SIG,
3333
BUTTON_PRESSED_SIG,
3434
BUTTON_RELEASED_SIG,
3535
BLINKY_WORK_SIG,
@@ -50,16 +50,16 @@ typedef struct {
5050
uint16_t toggles; /* number of toggles of the signal */
5151
} ButtonWorkEvt;
5252

53-
void Blinky1_ctor(void);
53+
void Blinky1_instantiate(void);
5454
extern SST_Task * const AO_Blinky1; /* opaque task pointer */
5555

56-
void Blinky3_ctor(void);
56+
void Blinky3_instantiate(void);
5757
extern SST_Task * const AO_Blinky3; /* opaque task pointer */
5858

59-
void Button2a_ctor(void);
59+
void Button2a_instantiate(void);
6060
extern SST_Task * const AO_Button2a; /* opaque task pointer */
6161

62-
void Button2b_ctor(void);
62+
void Button2b_instantiate(void);
6363
extern SST_Task * const AO_Button2b; /* opaque task pointer */
6464

6565
#endif /* BLINKY_BUTTON_H_ */

sst0_c/examples/blinky_button/bsp_ek-tm4c123gxl.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,7 @@ void SysTick_Handler(void); /* prototype */
6060
void SysTick_Handler(void) { /* system clock tick ISR */
6161
BSP_d1on();
6262

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

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

sst0_c/examples/blinky_button/bsp_nucleo-c031c6.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,7 @@ void SysTick_Handler(void); /* prototype */
5454
void SysTick_Handler(void) { /* system clock tick ISR */
5555
BSP_d1on();
5656

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

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

sst0_c/examples/blinky_button/bsp_nucleo-h743zi.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,7 @@ void SysTick_Handler(void); /* prototype */
5656
void SysTick_Handler(void) { /* system clock tick ISR */
5757
BSP_d1on();
5858

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

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

sst0_c/examples/blinky_button/bsp_nucleo-l053r8.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,7 @@ void SysTick_Handler(void); /* prototype */
5555
void SysTick_Handler(void) { /* system clock tick ISR */
5656
BSP_d1on();
5757

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

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

0 commit comments

Comments
 (0)