在STM32上使用FreeRTOS进行任务切换时出现硬故障

时间:2015-11-30 18:15:59

标签: gcc stm32 freertos

我将应用程序从Tiva TM4C123gh6pm(Cortex-M4)移至STM32F446(也是Cortex-M4)。

我对两者使用通用的初始化例程,它适用于基本应用程序。

__attribute__(( naked ))
void ResetISR(void)
{

/*
 * This function is already started in Thread mode.
 * First the Control register will be set to use
 * the process stack.
 *
 * For more details about stacks, see page 2-2 of the DUI0553A
 * and page 74 of the Data Sheet.
 */

/*
 * Stack for the Thread Mode is selected by the ASP flag
 * of the Control register.
 *
 * For more details about the register, see
 * pp. 2-9 - 2.10 of the DUI0553A and
 * pp. 88 - 89 of the Data Sheet.
 */
__asm volatile("    MRS     r0, control         ");  /* r0 = control      */
__asm volatile("    ORR     r0, r0, #0x00000002 ");  /* r0 |= 2           */
__asm volatile("    MSR     control, r0         ");  /* control = r0      */
__asm volatile("    ISB                         ");  /* wait until synced */

/*
 * After the Thread Mode stack has been set,
 * its stack pointer must be set.
 */
__asm volatile("    LDR     r1, =_psp   ");   /* r1 = &_psp */
__asm volatile("    LDR     r0, [r1]    ");   /* r0 = *r1   */
__asm volatile("    MOV     sp, r0      ");   /* sp = r0    */
__asm volatile("    ISB                 ");


/*
 * Then initialize the BSS section.
 * Note that the BSS section may include the stack,
 * in this case initialization would also overwrite
 * local variables (in the stack), so the implementation
 * in C would probably not execute correctly. For this
 * reason, this task must be implemented in assembler.
 */

__asm volatile("    LDR     r0, =_bss        ");  /* r0 = &_bss             */
__asm volatile("    LDR     r1, =_ebss       ");  /* r1 = &_ebss            */
__asm volatile("    MOV     r2, #0           ");  /* r2 = 0                 */
__asm volatile("    .thumb_func              ");
__asm volatile("bss_zero_loop:               ");
__asm volatile("    CMP     r0, r1           ");  /* if (r0<r1)             */
__asm volatile("    IT      lt               ");  /* {                      */
__asm volatile("    STRLT   r2, [r0], #4     ");  /*   *(r0++) = r2         */
__asm volatile("    BLT     bss_zero_loop    ");  /*   goto bss_zero_loop } */

/*
 * Most likely the compiler will be able to
 * copy data initializers without pushing
 * these local variables to stack.
 */
uint32_t* src;
uint32_t* dest;

/*
 * Copy the data segment initializers from flash to SRAM.
 */
src = &_etext;
for( dest = &_data; dest < &_edata; )
{
    *dest++ = *src++;
}

_init();
main();
}

然而,一旦我使用线程,我就会遇到一个严重的错误。

void blinky(void *args) {

    printf("starting blinky\n");
    while (1) {
        DEFAULT_LED_TOGGLE;

        list_freertos_tasks();

        vTaskDelay(5000 / portTICK_PERIOD_MS);
    }
}

(这是延迟之后)

2015-11-30 18:59:11,722 - INFO # starting scheduler
2015-11-30 18:59:11,722 - INFO # starting blinky
2015-11-30 18:59:16,654 - INFO #    --|Hard Fault|-- 
2015-11-30 18:59:16,660 - INFO # r0:        0   r12: a5a5a5a5
2015-11-30 18:59:16,661 - INFO # r1: 20000fe4    lr:  8002263
2015-11-30 18:59:16,665 - INFO # r2: 10000000    pc:  80020de
2015-11-30 18:59:16,672 - INFO # r3: e000ed04   psr: 61000000
2015-11-30 18:59:16,672 - INFO # HFSR: 40000000 CFSR: 40000

我对两者使用相同的编译器选项。

CFLAGS += -mlittle-endian -mcpu=cortex-m4 -march=armv7e-m -mthumb
CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard

TI和ST的CM4之间是否存在一些我不知道的细微差别?

我还尝试为STM32F446-Nucleo编译一个不同的FreeRTOS项目,一位同事成功创建并与Keil一起运行。 它与我的arm-none-eabi-gcc (15:4.9.3+svn227297-1) 4.9.3 20150529 (prerelease)配置崩溃。

(我以前使用gcc 4.8.4得到了相同的结果,我升级了希望它可以解决这个问题)

1 个答案:

答案 0 :(得分:1)

请注意下一页上的粗体红色文字,其中突出显示了STM32部件所需的额外步骤:http://www.freertos.org/RTOS-Cortex-M3-M4.html

如果这是问题,那么定义configASSERT()将为您捕获它:http://www.freertos.org/a00110.html#configASSERT