I'm in the process of getting uC/OS-III working on an NXP MIMXRT1062 using the MCUXpresso ide with gcc compiler. When the OS starts multitasking it calls the OSStartHighRdy function:
.thumb_func
OSStartHighRdy:
CPSID I @ Prevent interruption during context switch
MOVW R0, #:lower16:NVIC_SYSPRI14 @ Set the PendSV exception priority
MOVT R0, #:upper16:NVIC_SYSPRI14
MOVW R1, #:lower16:NVIC_PENDSV_PRI
MOVT R1, #:upper16:NVIC_PENDSV_PRI
STRB R1, [R0]
MOVS R0, #0 @ Set the PSP to 0 for initial context switch call
MSR PSP, R0
MOVW R0, #:lower16:OS_CPU_ExceptStkBase @ Initialize the MSP to the OS_CPU_ExceptStkBase
MOVT R0, #:upper16:OS_CPU_ExceptStkBase
LDR R1, [R0]
MSR MSP, R1
BL OSTaskSwHook @ Call OSTaskSwHook() for FPU Push & Pop
MOVW R0, #:lower16:OSPrioCur @ OSPrioCur = OSPrioHighRdy;
MOVT R0, #:upper16:OSPrioCur
MOVW R1, #:lower16:OSPrioHighRdy
MOVT R1, #:upper16:OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
MOVW R0, #:lower16:OSTCBCurPtr @ OSTCBCurPtr = OSTCBHighRdyPtr;
MOVT R0, #:upper16:OSTCBCurPtr
MOVW R1, #:lower16:OSTCBHighRdyPtr
MOVT R1, #:upper16:OSTCBHighRdyPtr
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] @ R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
MSR PSP, R0 @ Load PSP with new process SP
MRS R0, CONTROL
ORR R0, R0, #2
BIC R0, R0, #4 @ Clear FPCA bit to indicate FPU is not in use
MSR CONTROL, R0
ISB @ Sync instruction stream
LDMFD SP!, {R4-R11, LR} @ Restore r4-11, lr from new process stack
LDMFD SP!, {R0-R3} @ Restore r0, r3
LDMFD SP!, {R12, LR} @ Load R12 and LR
LDMFD SP!, {R1, R2} @ Load PC and discard xPSR
CPSIE I
BX R1
However, the stack overflows after this line MSR MSP, R1
This is my main function:
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MIMXRT1062.h"
#include "fsl_debug_console.h"
/* TODO: insert other include files here. */
#include "../uC-OS3/uCOS-III/Source/os.h"
#include "start_task.h"
#include "../BSP/bsp_clk.h"
#include "../BSP/bsp_int.h"
#include "../BSP/bsp_os.h"
#include "../uC-OS3/uC-LIB/lib_mem.h"
#include "os_app_hooks.h"
/* TODO: insert other definitions and declarations here. */
void PendSV_Handler(void)
{
OS_CPU_PendSVHandler();
}
void SysTick_Handler(void)
{
OS_CPU_SysTickHandler();
}
/*
* @brief Application entry point.
*/
int main(void)
{
OS_ERR err;
/* Init board hardware. */
BOARD_ConfigMPU();
BSP_ClkInit();
SysTick_Config(SystemCoreClock/600000);
BSP_IntInit();
BSP_OS_TickInit();
Mem_Init();
CPU_IntDis();
CPU_Init();
// 1. Call OSInit
OSInit(&err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
App_OS_SetAllHooks();
OSSchedRoundRobinCfg(DEF_ENABLED, 10, &err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
// 2. Call OSTaskCreate only once after call to OSInit
OSTaskCreate(&startTaskTCB,
startTaskName,
startTask,
(void *)0,
startTaskPrio,
&startTaskStk[0],
startTaskStkLimit,
startTaskStkSize,
startTaskQSize,
startTaskQuanta,
(void *)0,
OS_OPT_TASK_NONE,
&err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
// 3. Call OSStart -- starts multitasking, doesn't return
OSStart(&err);
while (1);
return 0;
}
This are the 3 tasks I have:
#include "start_task.h"
#include "blinky_task.h"
#include "other_task.h"
#include "../BSP/bsp_os.h"
OS_TCB startTaskTCB;
CPU_CHAR* startTaskName = "START TASK";
OS_PRIO startTaskPrio = 2;
CPU_STK_SIZE startTaskStkLimit = START_TASK_STK_SIZE/10;
CPU_STK_SIZE startTaskStkSize = START_TASK_STK_SIZE;
CPU_STK startTaskStk[START_TASK_STK_SIZE];
OS_MSG_QTY startTaskQSize = 0;
OS_TICK startTaskQuanta = 0;
void startTask(void *p_arg)
{
(void)p_arg;
OS_ERR err;
BSP_OS_TickEnable();
// Create all tasks needed
OSTaskCreate(&blinkyTaskTCB,
blinkyTaskName,
blinkyTask,
(void *)0,
blinkyTaskPrio,
&blinkyTaskStk[0],
blinkyTaskStkLimit,
blinkyTaskStkSize,
blinkyTaskQSize,
blinkyTaskQuanta,
(void *)0,
OS_OPT_TASK_NONE,
&err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
OSTaskCreate(&otherTaskTCB,
otherTaskName,
otherTask,
(void *)0,
otherTaskPrio,
&otherTaskStk[0],
otherTaskStkLimit,
otherTaskStkSize,
otherTaskQSize,
otherTaskQuanta,
(void *)0,
OS_OPT_TASK_NONE,
&err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
while (DEF_ON)
{
// Just have a small delay
OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
}
}
#include "blinky_task.h"
#include "stdbool.h"
#include "fsl_gpio.h"
OS_TCB blinkyTaskTCB;
CPU_CHAR* blinkyTaskName = "BLINKY TASK";
OS_PRIO blinkyTaskPrio = 3;
CPU_STK_SIZE blinkyTaskStkLimit = BLINKY_TASK_STK_SIZE/10;
CPU_STK_SIZE blinkyTaskStkSize = BLINKY_TASK_STK_SIZE;
CPU_STK blinkyTaskStk[BLINKY_TASK_STK_SIZE];
OS_MSG_QTY blinkyTaskQSize = 0;
OS_TICK blinkyTaskQuanta = 0;
static bool blinkState = true;
void blinkyTask(void *p_arg)
{
(void)p_arg;
OS_ERR err;
gpio_pin_config_t ledPinConf = { kGPIO_DigitalOutput, 1, kGPIO_NoIntmode };
GPIO_PinInit(GPIO1, 8U, &ledPinConf);
while (DEF_ON)
{
// Delay between LED toggle
OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
// Toggle LED
if (blinkState)
{
GPIO_PinWrite(GPIO1, 8U, 0U);
blinkState = false;
}
else
{
GPIO_PinWrite(GPIO1, 8U, 1U);
blinkState = true;
}
}
}
#include "other_task.h"
OS_TCB otherTaskTCB;
CPU_CHAR* otherTaskName = "OTHER TASK";
OS_PRIO otherTaskPrio = 4;
CPU_STK_SIZE otherTaskStkLimit = OTHER_TASK_STK_SIZE/10;
CPU_STK_SIZE otherTaskStkSize = OTHER_TASK_STK_SIZE;
CPU_STK otherTaskStk[OTHER_TASK_STK_SIZE];
OS_MSG_QTY otherTaskQSize = 0;
OS_TICK otherTaskQuanta = 0;
void otherTask(void *p_arg)
{
(void)p_arg;
OS_ERR err;
while (DEF_ON)
{
OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
}
}
The task header files:
#ifndef START_TASK_H_
#define START_TASK_H_
#include "../uC-OS3/uCOS-III/Source/os.h"
#define START_TASK_STK_SIZE (256U)
extern OS_TCB startTaskTCB;
extern CPU_CHAR* startTaskName;
extern OS_PRIO startTaskPrio;
extern CPU_STK_SIZE startTaskStkLimit;
extern CPU_STK_SIZE startTaskStkSize;
extern CPU_STK startTaskStk[START_TASK_STK_SIZE];
extern OS_MSG_QTY startTaskQSize;
extern OS_TICK startTaskQuanta;
void startTask(void *p_arg);
#endif /* START_TASK_H_ */
#ifndef BLINKY_TASK_H_
#define BLINKY_TASK_H_
#include "../uC-OS3/uCOS-III/Source/os.h"
#define BLINKY_TASK_STK_SIZE (256U)
extern OS_TCB blinkyTaskTCB;
extern CPU_CHAR* blinkyTaskName;
extern OS_PRIO blinkyTaskPrio;
extern CPU_STK_SIZE blinkyTaskStkLimit;
extern CPU_STK_SIZE blinkyTaskStkSize;
extern CPU_STK blinkyTaskStk[BLINKY_TASK_STK_SIZE];
extern OS_MSG_QTY blinkyTaskQSize;
extern OS_TICK blinkyTaskQuanta;
void blinkyTask(void *p_arg);
#endif /* BLINKY_TASK_H_ */
#ifndef OTHER_TASK_H_
#define OTHER_TASK_H_
#include "../uC-OS3/uCOS-III/Source/os.h"
#define OTHER_TASK_STK_SIZE (256U)
extern OS_TCB otherTaskTCB;
extern CPU_CHAR* otherTaskName;
extern OS_PRIO otherTaskPrio;
extern CPU_STK_SIZE otherTaskStkLimit;
extern CPU_STK_SIZE otherTaskStkSize;
extern CPU_STK otherTaskStk[OTHER_TASK_STK_SIZE];
extern OS_MSG_QTY otherTaskQSize;
extern OS_TICK otherTaskQuanta;
void otherTask(void *p_arg);
#endif /* OTHER_TASK_H_ */
I can also include the uC/OS-III code if needed.
At the moment a hardfault occurs after the last task (otherTask) and I'm not sure where to begin looking.
I have increased and decreased the task's stack size but no change.
The mcu's stack is 4k and after the MSR MSP, R1
line, it goes to around 120k