This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Can't access variable in IRQ Handler

Hi,

I'm getting familiar with my nRF52 DK (PCA 10040).

I stumbled on something when I was doing an application that toggles LED1 on every TIMER0 event (200ms). Here is my code

#include "stdint.h"
#include "nrf52.h"

//volatile uint32_t varA;	<POS A>

void initSystem (void) {	
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;	
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { }

    NRF_TIMER0->MODE		= 0;
    NRF_TIMER0->BITMODE		= 3;
    NRF_TIMER0->PRESCALER	= 5;
    NRF_TIMER0->CC[0]		= 100000;		// TIMER0_IRQn event each 200ms

    NRF_TIMER0->INTENSET	= (1<<16);

    NRF_TIMER0->TASKS_CLEAR = 1;
    NRF_TIMER0->SHORTS		= 1;
    NRF_TIMER0->TASKS_START = 1;

    NVIC_SetPriority(TIMER0_IRQn, 7);
    NVIC_ClearPendingIRQ(TIMER0_IRQn);
    NVIC_EnableIRQ(TIMER0_IRQn);
}

int main (void) {		
    NRF_P0->DIRSET = (1<<17);
    NRF_P0->OUTSET = (1<<17);

    initSystem();

    while (1) { }
}

void TIMER0_IRQHandler (void) {	
    volatile uint32_t varA;		// <POS B>

    varA = NRF_P0->OUTSET & (1<<17);

    if (varA)
	    NRF_P0->OUTCLR = (1<<17);
    else
	    NRF_P0->OUTSET = (1<<17);	

    NRF_TIMER0->EVENTS_COMPARE[0] = 0;
}

Everything is great. But if I move the declaration of the varA to the top (i.e. in my opinion declaring it as a global variable) it does not work. I don't get a compile or link error. The LED just won't toggle.

Why can't I access global variables inside my IRQ Handler??

NOTE: I'm only using CMSIS: Core and Device startup

  • BTW, the var is not really volatile, only the IO regs, since you only write and read the var from one thread (the IRQ handler.) But I suppose you declared it volatile to insure it was not optimized away. The Nordic definitions should declare the IO regs as volatile to insure reads and writes are not optimized away. But you already said you have tested without optimizing.

  • I also think there is one or more options I should select/deselect in my project. But there are so many options which I have no clue. I use one of the latest versions of Keil and the software packs (Installed computer last week). But I'll try some more when I get access to the DK again.

  • Code works in the debugger but not when I run it outside the debugger..

  • That is really strange. The debugger should have no effect: AFAIK it doesn't change your code or the timing of it at all (since the JTAG that assists the debugger server and client is in hw.) How exactly are you proceeding? As I recall, when you terminate the debugger client (from Keil) you app keeps on running on the target (or will restart when you unplug and plug in the USB cable.)

  • I Rebuild the code, load it to the target using J-LINK / J-TRACE Cortex driver with the option Reset and Run. Then I start the debugger J-Link / J-Trace Adapter with Port = SW @ Max Clock 5 Mhz. I set a breakpoint at "varA = NRF_P0->OUTSET & (1<<17) in the IRQHandler Press Run (F5) and the code stops at the breakpoint. From here I can either press Run again or single step the IRQHandler. In both ways the LED is toggled. When I stop the debugger I'm not sure if the code is still running on the DK because the LED doesn't toggle anymore. Doesn't help if unplug/plug the USB cable. I'm running in evaluation mode if that is a problem? My code is faaaar less than the 32k limit.. Everything is default in my project options except i'm also producing a Hex file and using J-LINK/J-TRACE Cortex driver instead of ULINK Pro Cortex Debugger

Related