Stack overflow after call to OSStartHighRdy (uC/OS-III)

122 Views Asked by At

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

0

There are 0 best solutions below