Hardfault when clicking restart during debugging using mcuxpresso (LPC4357 + FreeRTOS + interrupt)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Hardfault when clicking restart during debugging using mcuxpresso (LPC4357 + FreeRTOS + interrupt)

1,281 Views
uaz
Contributor II

Hi,

I wonder if anyone else get the same problem as me. When running in debug, I am not able to restart the program because clicking restart will jump to hardfault (INVPC). I need to stop and restart debugging in order to restart my program and this consumes a lot of time.

I found out that this happens when I use an interrupt. When I disable the interrupt, I can restart the program during debugging as many time as I wants. This is my example code (I added a timer interrupt to Freertos blinky example):

#include "board.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

/*****************************************************************************
 * Private types/enumerations/variables
 ****************************************************************************/
#define TICKRATE_HZ 1
/*****************************************************************************
 * Public types/enumerations/variables
 ****************************************************************************/

/*****************************************************************************
 * Private functions
 ****************************************************************************/

/* Sets up system hardware */
static void prvSetupHardware(void)
{
     SystemCoreClockUpdate();
     Board_Init();

     /* Initial LED0 state is off */
     Board_LED_Set(0, false);
}

/* LED1 toggle thread */
static void vLEDTask1(void *pvParameters) {
     bool LedState = false;

     while (1) {
          Board_LED_Set(0, LedState);
          LedState = (bool) !LedState;

          /* About a 3Hz on/off toggle rate */
          vTaskDelay(configTICK_RATE_HZ / 6);
     }
}

/* LED2 toggle thread */
static void vLEDTask2(void *pvParameters) {
     bool LedState = false;

     while (1) {
          Board_LED_Set(1, LedState);
          LedState = (bool) !LedState;

          /* About a 7Hz on/off toggle rate */
          vTaskDelay(configTICK_RATE_HZ / 14);
     }
}

/* UART (or output) thread */
static void vUARTTask(void *pvParameters) {
     int tickCnt = 0;

     while (1) {
          DEBUGOUT("Tick: %d \r\n", tickCnt);
          tickCnt++;

          /* About a 1s delay here */
          vTaskDelay(configTICK_RATE_HZ);
     }
}

/*****************************************************************************
 * Public functions
 ****************************************************************************/

/**
 * @brief     main routine for FreeRTOS blinky example
 * @return     Nothing, function should not exit
 */
int main(void)
{
     uint32_t timerFreq;
     prvSetupHardware();

     /* Enable timer 1 clock and reset it */
     Chip_TIMER_Init(LPC_TIMER1);
     Chip_RGU_TriggerReset(RGU_TIMER1_RST);
     while (Chip_RGU_InReset(RGU_TIMER1_RST)) {}

     /* Get timer 1 peripheral clock rate */
     timerFreq = Chip_Clock_GetRate(CLK_MX_TIMER1);

     /* Timer setup for match and interrupt at TICKRATE_HZ */
     Chip_TIMER_Reset(LPC_TIMER1);
     Chip_TIMER_MatchEnableInt(LPC_TIMER1, 1);
     Chip_TIMER_SetMatch(LPC_TIMER1, 1, (timerFreq / TICKRATE_HZ));
     Chip_TIMER_ResetOnMatchEnable(LPC_TIMER1, 1);
     Chip_TIMER_Enable(LPC_TIMER1);

     /* Enable timer interrupt */
     NVIC_EnableIRQ(TIMER1_IRQn);
     NVIC_ClearPendingIRQ(TIMER1_IRQn);

     /* LED1 toggle thread */
     xTaskCreate(vLEDTask1, "vTaskLed1", configMINIMAL_STACK_SIZE,
               NULL, (tskIDLE_PRIORITY + 1UL), (TaskHandle_t *) NULL);

     /* LED2 toggle thread */
     xTaskCreate(vLEDTask2, "vTaskLed2", configMINIMAL_STACK_SIZE,
               NULL, (tskIDLE_PRIORITY + 1UL), (TaskHandle_t *) NULL);

     /* UART output thread, simply counts seconds */
     xTaskCreate(vUARTTask, "vTaskUart", configMINIMAL_STACK_SIZE,
               NULL, (tskIDLE_PRIORITY + 1UL), (TaskHandle_t *) NULL);

     /* Start the scheduler */
     vTaskStartScheduler();

     /* Should never arrive here */
     return 1;
}

void TIMER1_IRQHandler(void)
{
     static BaseType_t xHigherPriorityTaskWoken;
     static int interruptCount = 0;

     if (Chip_TIMER_MatchPending(LPC_TIMER1, 1)) {
          Chip_TIMER_ClearMatch(LPC_TIMER1, 1);
          interruptCount++;
     }
}

I also found that the rtos will crash after running it for several hours.

Can someone enlighten how this hardfault occurs? It will not occur if the timer interrupt is not enabled.

Does anyone ever succeeded to have stable freertos build with nxp?

Thanks

UAZ

Labels (2)
0 Kudos
6 Replies

961 Views
uaz
Contributor II

Hi, anyone with similar issue? Or is this CMSIS-DAP limitation? Thanks

0 Kudos

961 Views
uaz
Contributor II

Hi all,

After trying countless of time, I still fail to solve the hardfault issue when restarting application during debugging. To confirm the problem, I successfully managed to generate the problem using lpcxpresso4367 board running freertos_tcpecho example from lpcopen v3.02. Seems like the problem will happen if Ethernet interrupt is enabled. (Ethernet interupt priority is configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY  + 1)

I believe the problem might be related to lpc-link2 debugger using CMSIS-DAP firmware. If I debug using J-Link firmware, I am able to restart debugging without hardfault.

Will this count as a bug?

0 Kudos

961 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Uaz,

The parameter configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY  is used to configure the tick interrupt priority for the FreeRtos, all the other peripheral interrupt priority should be less than this configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY value so that the tick interrupt is not effected, which can guarantee that the Freertos can run reliably.

Yes, I think that you can only use priority 7 or 6 for my peripheral interrupts if the configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY is set up as 5.

I think you can set the configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY to another value for example 4.

Regarding the question that "I also found that the rtos will crash after running it for several hours.", as Con Verse  said that probably the memory leakage of Freertos leads to the system crash, anyway, this issue is tough.

BR

Xiangjun Rong

0 Kudos

961 Views
converse
Senior Contributor V

"I also found that the rtos will crash after running it for several hours."

I would guest that this improbably due to memory leak - i.e. there is memory being located and not being fee. At some point ,a memory allocation will fail (return a null pointer) which is then being used unchecked. 

"Does anyone ever succeeded to have stable freertos build with nxp?"

yes, FreeRTOS is very stable.

0 Kudos

961 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

From your description, I see that if you delete the Timer code, there is not any issue. I have checked your code, frankly speaking, I have not found problem.

But your code does not set the Timer interrupt priority, in general, any peripheral interrupt source priority must be less than the FreeRtos system interrupt priority. In default, the system tick priority is set up as in FreeRTOSConfig.h, it is defined as

#define configMAX_PRIORITIES (5)

so you have to set up the priority of Timer greater than 5 in IPRx register.

Hope it can help you

BR

XiangJun Rong

0 Kudos

961 Views
uaz
Contributor II

I believe you wanted to say configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY correct?

From my understanding, configMAX_PRIORITIES is used to define the maximum value for freertos task, and it should not have anything to do with NVIC priority.

After reading the datasheet of LPC4357, there are only 3 priority bits per interrupt. So I can only use priority 7 or 6 for my peripheral interrupts (must be bigger than 5)?

Is it possible to lower configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY to lower than 5 so that I get more interrupt priority range for my peripherals?

Thanks,

UAZ

0 Kudos