1818
1919/* -- Defines ------------------------------------------------------------- */
2020
21+ #define FILL 0xBABEFACE // for task allocation debugging
22+ #define CANARY 0xDEADBEEF
23+ #define CANARY_SIZE 16
2124#define TRIGGER_PendSV *(uintptr_t volatile *)0xE000ED04 = (1U << 28)
2225
2326/* -- Types --------------------------------------------------------------- */
2427
2528/* -- Private Function Declarations --------------------------------------- */
29+ /**
30+ * \details Safely catches an unexpected return from a task.
31+ * Any task that returns is marked as 'terminated' and moved accordingly.
32+ *
33+ */
34+ void task_exit_guard (void );
2635
2736/**
2837 * \brief Updates the task control blocks stack_usage
@@ -182,8 +191,7 @@ void initializeStack(TaskControlBlock* tcb) {
182191 // - non-critical registers are initialized to their index
183192 * (-- stack_ptr ) = (1U << 24 ); ///< Set thumb state bit in EPSR
184193 * (-- stack_ptr ) = (uintptr_t )tcb -> task_handle ; ///< Set PC to task function handle
185- * (-- stack_ptr ) = 0xFFFFFFF9U ; ///< Set LR register for MSP thread mode
186- // *(--stack_ptr) = 0xFFFFFFFDU; ///< Set LR register for PSP thread mode
194+ * (-- stack_ptr ) = (uintptr_t )task_exit_guard ; // LR: Return trap
187195 * (-- stack_ptr ) = 0x0000000CU ; ///< Set R12 register deafult to its index
188196 * (-- stack_ptr ) = 0x00000003U ; ///< Set R3 register deafult to its index
189197 * (-- stack_ptr ) = 0x00000002U ; ///< Set R2 register deafult to its index
@@ -201,11 +209,11 @@ void initializeStack(TaskControlBlock* tcb) {
201209 * (-- stack_ptr ) = 0x00000004U ; ///< Set R4 register deafult to its index
202210 tcb -> stack_pointer = stack_ptr ;
203211 // Fill unused process stack with known value
204- while (stack_ptr > tcb -> stack_overflow + 8 ) {
205- * (-- stack_ptr ) = 0xBABEFACEU ;
212+ while (stack_ptr > tcb -> stack_overflow + CANARY_SIZE ) {
213+ * (-- stack_ptr ) = FILL ;
206214 }
207215 while (stack_ptr > tcb -> stack_overflow ) {
208- * (-- stack_ptr ) = 0xDEADBEEFU ; ///< set top 8 bytes to something else
216+ * (-- stack_ptr ) = CANARY ; ///< set top 8 bytes to something else
209217 }
210218}
211219
@@ -224,7 +232,17 @@ void SysTick_Handler(void) {
224232 uint32_t primask ;
225233 primask = jock_os_enter_critical_section ();
226234 JOCKTOSScheduler .tick_count ++ ;
227- jock_os_switch_running_task (& JOCKTOSScheduler .ready );
235+ TaskControlBlock * * dest = & JOCKTOSScheduler .ready ;
236+ TaskControlBlock * tcb = JOCKTOSScheduler .running ;
237+ uint32_t * ptr = (uint32_t * )tcb -> stack_overflow + CANARY_SIZE ;
238+ for (int i = 0 ; i < CANARY_SIZE ; i ++ ) {
239+ if (* (-- ptr ) != CANARY ) {
240+ if (tcb == & usr_main_tcb ) break ; // ignore stack canary for main [TODO]
241+ dest = & JOCKTOSScheduler .terminated ;
242+ break ;
243+ }
244+ }
245+ jock_os_switch_running_task (dest );
228246 jock_os_leave_critical_section (primask );
229247
230248}
@@ -294,7 +312,7 @@ void monitorJOCKTOS(void* arg) {
294312}
295313
296314
297- void idleJOCKTOS (void * arg ) {
315+ void idleJOCKTOS (void * arg __attribute__(( unused )) ) {
298316 /* Disable interrupts to make sure that the busy flag does not get
299317 modified between the check in the while condition and the system
300318 sleep */
@@ -351,4 +369,10 @@ void idleJOCKTOS(void* arg) {
351369 // TODO: Figure out how to low power
352370}
353371
354-
372+ __attribute__((noreturn ))
373+ void task_exit_guard (void ) {
374+ uint32_t primask = jock_os_enter_critical_section ();
375+ JOCKTOSScheduler .running -> state = TERMINATED ;
376+ jock_os_switch_running_task (& JOCKTOSScheduler .terminated );
377+ jock_os_leave_critical_section (primask );
378+ }
0 commit comments