vPortSetInterruptMask causes interrupt issue

MCU: Kinetis K10 – Arm Cortex M4
IDE: CodeWarrior 10.2 I know I’m not supposed to set any interrupt priorities lower than configMAX_SYSCALL_INTERRUPT_PRIORITY for functions that call into RTOS API. So, I’ve been careful about that. However, I’m still seeing a VERY WEIRD issue. When I set UART3’s Error interrupt, the call into vPortSetInterruptMask disables my Periodic Interrupt Timer (PIT0)! I’m not using UART3, but I wanted to to set all unused interrupts to level 15 (Lowest priority) just to be safe. It’s strange because no other interrupts trigger this error. Any thoughts on what I’m seeing this odd behavior? MY PIT0 is set to interrupt level 0 (highest priority). Maybe I just have a misunderstanding of how things work with this RTOS. I thought this PIT0 interrupt would NEVER be disabled. I need that to be the cause since it’s keeping track of time in my system.

vPortSetInterruptMask causes interrupt issue

I know I’m not supposed to set any interrupt priorities lower than configMAX_SYSCALL_INTERRUPT_PRIORITY for functions that call into RTOS API. So, I’ve been careful about that.
If you mean assign them a priority that is numerically lower, then that statement is correct, but remember that numerically lower means effectively higher on the Cortex-M. You are right that if you timer is truly at priority 0 it should never be disabled, especially if your UART interrupt priority is 15, and the timer interrupt is not making any calls into the RTOS API. Can you see why the timer is not running?  FreeRTOS only manipulates interrupt masks using the Cortex-M BASEPRI register – and an interrupt of priority 0 cannot be masked using BASEPRI.  So either interrupts are globally disabled (which FreeRTOS doesn’t do) or the timer has stopped for some reason.  Are you using *any* functions that manipulate any of the Cortex-M interrupt masks other than taskENTER_CRITICAL() and taskEXIT_CRITICAL(), could anything be globally disabling interrupts in the Cortex-M core itself?  (by calling the “cpsid i” asm instruction)? Regards.

vPortSetInterruptMask causes interrupt issue

Well, based on that (I’m just now learning about BASEPRI), this is looking a LOT like a Freescale Bug. I had this code in place to determine it was the BASEPRI causing my trouble. The first delay_ms() works, but the second falls into the trap I’ve set.
    delay_ms( 5 );
    portDISABLE_INTERRUPTS();
    delay_ms( 5 );
Here is my Delay_ms() function:
/* ===============================================================================================
==  FUNCTION DESCRIPTION:
==      Delays to for specified amount of milliseconds.
==  For safety, 1ms is added to requested ms delay because timer could technically rollover 1us later. 
==
==  OUTPUTS:
==  N/A
== =============================================================================================*/
void TIMERS__delay_ms
  (
  timer_t  delay_amount
  )
    {
    /* Local Variables. */
    u32  last_count;
    u32  current_count = 0;
    u32  trouble_counter = 0;
    u32  max_trouble_count = 10000; //Observed trouble counts of 8,303 up to 9,060 while testing successes at 100MHz. 
    
    /* Record the current count from the interrupt counter. */
    last_count = SYSTICK__counter__1ms;
    /* Loop until the local counter matches the specified delay. */
    while( TRUE ) 
    {
    /* Check if interrupt counter has been updated. */
    if( last_count != SYSTICK__counter__1ms )
        {       
        current_count++;            //Increment local counter.
        if( current_count >= (delay_amount + 1) )   break;
        
        last_count = SYSTICK__counter__1ms; //Record current count;
        trouble_counter = 0;        //Reset trouble counter.
        }

    if( ++trouble_counter >= max_trouble_count ) 
        {
        //TODO: Figure out why this sometimes occurs.
        DEBUG__print_error_message( "SysTick Interrupt stopped triggering!" );
        //DEBUG__assert( __FILE__, __func__, __LINE__ );
        break;
        }
    }
    } /* TIMERS__delay_ms() */
Here’s a snapshot of my PIT0 interrupt priority.
NVICIP84:
With NVICIP84 set to 0 and BASEPRI set to 0x50, I can clearly see my interrupt has stopped ticking by running through the delay_ms() function. If I use my debugger to move back to the top of the function, set BASEPRI 0x00, then everything runs fine again. Setting BASEPRI to any valid value causes the interrupt to stop triggering again!!! So, looks like a Freescale issue. I’d assume the ARM core is fine since it’s been around much longer.  Is there anything I’m missing?

vPortSetInterruptMask causes interrupt issue

And, just to throw a completely random curve-ball in there… As stated in the previous email, running my delay_ms() function with these conditions causes PIT0 to stop interrupting.
NVICIP84 = 0
BASEPRI = 0x50 Now if I run delay_ms() function with the EXACT SAME conditions, but update NVICIP68 (UART 3’s Error Interrupt) to be 0x00 through 0x04, my PIT0 interrupts starts triggering again!!! Richard, this is now apparent to me that this is a non-FreeRTOS-related issue. My apologies for posting it on your forum. But, you do seem to have an excellent grasp on the Kinetis (ARM Cortex) MCU’s. I would be very grateful for any input you have on this matter.

vPortSetInterruptMask causes interrupt issue

I’m not following some of this but have some comments
delay_ms( 5 );
portDISABLE_INTERRUPTS();
delay_ms( 5 );
You are calling portDISABLE_INTERRUTPS() but don’t appear to be re-enabling them. In that case no interrupts will execute at all, ever. In a FreeRTOS application you should only use taskENTER_CRITICAL() and taskEXIT_CRITICAL() to enter and exit critical sections, and not use portDISABLE_INTERRUPTS() or portENABLE_INTERRUPTS() unless you are absolutely sure about the internal workings of the chip and the FreeRTOS port.
void TIMERS__delay_ms
  (
  timer_t  delay_amount
  )
    {
    /* Local Variables. */
    u32  last_count;
    u32  current_count = 0;
    u32  trouble_counter = 0;
    u32  max_trouble_count = 10000; //Observed trouble counts of 8,303 up to 9,060 while testing successes at 100MHz.
   
    /* Record the current count from the interrupt counter. */
    last_count = SYSTICK__counter__1ms;
    /* Loop until the local counter matches the specified delay. */
    while( TRUE )
{
/* Check if interrupt counter has been updated. */
if( last_count != SYSTICK__counter__1ms ) FreeRTOS uses the SYSTICK itself, and the tick rate is set by configTICK_RATE_HZ in FreeRTOS. Are you trying to use SYSTICK too? If you configured SYSTICK before calling vTaskStartScheduler() then FreeRTOS will have just overwritten your settings. If you configure SYSTICK from a task after calling vTaskStartScheduler() then the scheduler will not start properly. If you want to delay in FreeRTOS you can use the vTaskDelay() and vTaskDelayUntil() functions, which will stop the calling task from using any processing time until the delay period is up.

vPortSetInterruptMask causes interrupt issue

edwards, I wasn’t using portDISABLE_INTERRUTPS() directly. I made the observation that when my code returned from the very first xQueueGenericCreate() call, my delay_ms() function was broke (Interrupts stopped occurring).
So, I followed the breadcrumbs all the way down to portDISABLE_INTERRUTPS() which was calling vPortSetInterruptMask, which was setting BASEPRI. I hacked in these delay_ms() calls around portDISABLE_INTERRUTPS() just to prove it was the BASEPRI causing my interrupt to stop firing. The portDISABLE_INTERRUTPS() sets the BASEPRI. So, all interrupts with priority level below BASEPRI will still occur. I had my PIT0 interrupt priority set to 0. So, it should never be disabled unless I purposely disable all interrupts. I was originally using SYSTICK, but when I observed these symptoms, I moved onto PIT0 for my unit to track time. That change however didn’t improve anything regarding this behavior. had simply followed the breadcrumbs xQueueGenericCreate

vPortSetInterruptMask causes interrupt issue

edwards, you asked some good questions which got me thinking more. Why wasn’t BASEPRI reset to 0 when returning from xQueueGenericCreate()? I did some digging and found something concerning.  The very first time I entered vPortEnterCritical(), the uxCriticalNesting variable was set to 0xaaaaaaaa. I see that is the value assigned during declaration of the variable, but it should be set to 0 in xPortStartScheduler(). But, xPortStartScheduler() is never getting called. I’m still learning about the FreeRTOS. Do I have something setup incorrectly here? It would appear so.

vPortSetInterruptMask causes interrupt issue

Since YOUR main() code is supposed to call vTaskStartScheduler() which will setup a few needed things and then call vPortStartScheduler() to start up the system, then you do seem to have something setup wrong. In fact, normally interrupts are totally disabled until vPortStartScheduler is called.

vPortSetInterruptMask causes interrupt issue

Just to confirm ignisuti’s comments in post 6.
You are calling portDISABLE_INTERRUTPS() but don’t appear to be re-enabling them. In that case no interrupts will execute at all, ever
On the Cortex-M portDISABLE_INTERRUPTS does not completely disable interrupts.  It only masks up to configMAX_SYSCALL_INTERRUPT_PRIORITY.  The reason not to use portDISABLE_INTERRUPTS is that it does not count the nesting depth, whereas taskENTER_CRITICAL() does.
The very first time I entered vPortEnterCritical(), the uxCriticalNesting variable was set to 0xaaaaaaaa.
This is done to prevent interrupts accidentally getting enabled by a FreeRTOS API function before the user is ready and the scheduler has started.  uxCriticalNesting() will get set to 0 and interrupts completely unmasked when the first task starts running. Do you have tasks running? Regards.

vPortSetInterruptMask causes interrupt issue

Richard,
Yes, I create two tasks and then call scheduler_start(). I looks like this wasn’t happening before, because I made a rather serious mistake and was calling RTOS API before I had a chance to call scheduler_start().
I believe I’ve got that sorted out now… Now…. I seem to be stuck in tel_task() and never switch over to SERVICES__main_loop(). Now might be a good time to update you guys on my level of knowledge with FreeRTOS. Very Little! Just learning the basics as I run into issues like these. The Port was done by another engineer.
So, let’s start from the basics. What do I need to do to enable SERVICES__main_loop() beyond what I show below?
    /* Initialize the MCU. */
    APP__STARTUP__initialize();
  
    /* Create RTOS Tasks. */
    task_create( tel_task,      "Telemetry Loop", 2 * 1024 / 4, NULL, 3, NULL );
    task_create( SERVICES__main_loop,   "Main Loop",      8 * 1024 / 4, NULL, 2, NULL );   
    
    /* Start the RTOS Scheduler. */
    scheduler_start();    

vPortSetInterruptMask causes interrupt issue

because I made a rather serious mistake and was calling RTOS API before I had a chance to call scheduler_start().
It is ok to call some RTOS API functions before the scheduler has started, but not all.  In particular, it is important not to try and cause a task switch, or call a blocking API function (this makes sense, because both of these actions are asking the scheduler to do something but the scheduler is not running).  You have to be particularly careful that interrupts don’t execute that call API functions which in turn attempt to do one of these things.  It is best therefore to limit the API usage to creating tasks, queues and semaphores before the scheduler starts, and to not enable interrupts before the scheduler starts. What you are doing in the code snippet looks to be ok, but you are not calling FreeRTOS API functions directly.  I presume your task_create() and scheduler_start() functions somehow map to, or wrap, xTaskCreate() and vTaskStartScheduler() respectively, but it depends on what else your wrapper functions are doing. Have you looked at the official example projects for your processor, or the more generic basic demos? Regards.