-1

I am trying to use the systick handler in MSP432 controller for context switching but the systick handler is never called. I'm not sure what I doing wrong I set the interrupt priority to the highest and set PendSV to the lowest. I do disable interrupts but always re enable them so I do not think that is the issue.

void OS_onStartup(void){
    SystemCoreClockUpdate();
    SysTick_Config(SystemCoreClock / 10000);
    NVIC_SetPriority(SysTick_IRQn, 0U);
    //*(uint32_t volatile *)0x0000003C  |= 0U;
}

void OS_init(void){
    // set the penSV interrupt priority to the lowest level
    *(uint32_t volatile *)0x00000038  |= (0xFFU << 16);
 }

 void SysTick_Handler(void) {
     ++l_tickCtr;
     __disable_interrupts(); // @suppress("Function cannot be resolved")
     OS_sched();
     __enable_interrupts(); // @suppress("Function cannot be resolved")
  }

int main() {

    MSP_start();
    OS_init();
    /* fabricate Cortex-M ISR stack frame for blinky1 */
    OSThread_start(&blinky1,
               &main_blinky1,
               stack_blinky1, sizeof(stack_blinky1));

    /* fabricate Cortex-M ISR stack frame for blinky2 */
    OSThread_start(&blinky2,
               &main_blinky2,
               stack_blinky2, sizeof(stack_blinky2));

    OSThread_start(&blinky3,
                   &main_blinky3,
                   stack_blinky3, sizeof(stack_blinky3));

    //transfer control to the RTOS to run threads

    OS_run();

   //return 0;
   }

void OS_run(){
    OS_sched();
    //to start interrupts
    __disable_interrupts(); // @suppress("Function cannot be resolved")
    OS_onStartup();
    __enable_interrupts(); // @suppress("Function cannot be resolved")
   //code should not execute
   //while(1){}
 }
Mperez
  • 85
  • 1
  • 6
  • Have you defined a `SysTick_Handler()`? You have not included it in your question. Check the [documentation](https://www.keil.com/pack/doc/CMSIS/Core/html/group__SysTick__gr.html) for `SysTick_Config()`, it returns a status which you are not checking, and there is a note about `__Vendor_SysTickConfig` which may apply. You should probably set the priority _before_ enabling the interrupt. Did you intend a 100us tick interval? – Clifford Feb 03 '21 at 18:15
  • I added the systick_handler above. I checked the return status for Systick_config and it is 0 so it should be good. I was messing with the value of the tick interval to see if it would call systick quicker. I originally had it every 10us I believe. The PendSV handler works with no problem so I am just confused. I read that systick_handler is actually an exception and not an interrupt but I don't think that holds any revelance. – Mperez Feb 03 '21 at 18:33
  • Your `OS_init()` looks suspicious. You are assigning the PendSV vector, which does not make much sense - and makes me wonder how the handler is working. Why not `NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1)` or just `NVIC_SetPriority(PendSV_IRQn, 255)`? – Clifford Feb 03 '21 at 18:55
  • In Cortex-M the term exception refers to the core vectors with negative IRQn numbers, the terms are used more-or-less interchangeably. Other vectors are implementation/vendor defined and referred to as interrupts. More generally an exception usually refers to an interrupt caused by an error condition, so talking about a systtick exception is not "narural". In this context there is essentially no difference. – Clifford Feb 03 '21 at 19:00
  • Are you sure `OS_onStartup()` is being called - we have to take it on trust since you are only providing fragments. – Clifford Feb 03 '21 at 19:44
  • OS_onStartup() does get called. I have step through the entirety of the code to verify that this is true. I added the code above. Would it be easier to add the files? Or is that too excessive? – Mperez Feb 03 '21 at 20:02
  • The issue wouldn't be that I create the systick_handler right? Would I have to do something since it isn't a predefined function? I assumed that the controller would look for the function called systick. – Mperez Feb 03 '21 at 20:39
  • I am not sure what you mean by "predefined'. The Systick_Handler is defined as a weak symbol usually in startup_.s in a CMSIS compliant runtime. Defining the function overrides the weak link. It is automatic so long as you use the exactly correct symbol name convention. – Clifford Feb 03 '21 at 22:38
  • Since you have a debugger, you can inspect the NVIC and related registers to verify the state and that interrupts are enabled and if the Stick interrupt is pending. – Clifford Feb 03 '21 at 22:45
  • systick does not go through the nvic, that is your first problem. – old_timer Feb 04 '21 at 12:27

1 Answers1

1

This:

    // set the penSV interrupt priority to the lowest level
    *(uint32_t volatile *)0x00000038  |= (0xFFU << 16);

does not do what the comment says. 0x00000038 is the default address of the PendSV vector and on MSP432 is a ROM address. The PendSV priority is set using the System Handler Priority Register 3 register which is at 0xE000ED20:

enter image description here

You could write the register directly, but it is far simpler to use the CMSIS NVIC_SetPriority():

NVIC_SetPriority( PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1 ) ;

Or

NVIC_SetPriority( PendSV_IRQn, 0xff ) ;

The first is generic and will work across different Cortex-M implementations.

Clifford
  • 88,407
  • 13
  • 85
  • 165