在 STM32 上使用 FreeRTOS 进行任务切换时出现硬故障
Hard Fault on task switch with FreeRTOS on STM32
我正在将我的应用程序从 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 和 运行 使用 Keil 编译不同的 FreeRTOS 项目。
它因我的 arm-none-eabi-gcc (15:4.9.3+svn227297-1) 4.9.3 20150529 (prerelease)
配置而崩溃。
(我之前用gcc 4.8.4也是一样的结果,我升级了希望它能解决这个问题)
请注意下一页中突出显示 STM32 部件所需的额外步骤的粗体红色文本:http://www.freertos.org/RTOS-Cortex-M3-M4.html
如果这是问题所在,那么定义 configASSERT() 将为您捕获它:http://www.freertos.org/a00110.html#configASSERT
我正在将我的应用程序从 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 和 运行 使用 Keil 编译不同的 FreeRTOS 项目。
它因我的 arm-none-eabi-gcc (15:4.9.3+svn227297-1) 4.9.3 20150529 (prerelease)
配置而崩溃。
(我之前用gcc 4.8.4也是一样的结果,我升级了希望它能解决这个问题)
请注意下一页中突出显示 STM32 部件所需的额外步骤的粗体红色文本:http://www.freertos.org/RTOS-Cortex-M3-M4.html
如果这是问题所在,那么定义 configASSERT() 将为您捕获它:http://www.freertos.org/a00110.html#configASSERT