使用gcc在STM32F4上的FreeRTOS堆栈损坏

时间:2013-02-19 14:17:18

标签: gcc arm freertos stack-corruption stm32f4discovery

我正在尝试在我的stm32f4discovery板上运行FreeRTOS。我已经安装了summon-arm-toolchain并创建了一个Makefile来编译我的代码。这是Makefile:

TOOLCHAIN_PATH:=/usr/local/sat/bin
TOOLCHAIN_PREFIX:=arm-none-eabi
OPTLVL:=0
FREERTOS:=..
STARTUP:=$(CURDIR)/startup
LINKER_SCRIPT:=$(FREERTOS)/Utilities/stm32_flash.ld
INCLUDE=-I$(CURDIR)
# Setting other include path...
BUILD_DIR = $(CURDIR)/build
BIN_DIR = $(CURDIR)/binary
vpath %.c  $(CURDIR)
# Setting other vpath...
vpath %.s $(STARTUP)
ASRC=startup_stm32f4xx.s
# Project Source Files
SRC+=stm32f4xx_it.c
SRC+=system_stm32f4xx.c
SRC+=main.c
# FreeRTOS Source Files
SRC+=port.c
SRC+=list.c
SRC+=queue.c
SRC+=tasks.c
SRC+=timers.c
SRC+=heap_2.c
SRC+=syscalls.c
SRC+=stm32f4xx_usart.c
# Other peripheral source files...
CDEFS=-DUSE_STDPERIPH_DRIVER
CDEFS+=-DSTM32F4XX
CDEFS+=-DHSE_VALUE=8000000
MCUFLAGS=-mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp
COMMONFLAGS=-O$(OPTLVL) -g -Wall
CFLAGS=$(COMMONFLAGS) $(MCUFLAGS) $(INCLUDE) $(CDEFS)
LDLIBS=
LDFLAGS=$(COMMONFLAGS) -fno-exceptions -ffunction-sections -fdata-sections -nostartfiles -Wl,--gc-sections,-T$(LINKER_SCRIPT)
OBJ = $(SRC:%.c=$(BUILD_DIR)/%.o)
CC=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-gcc
LD=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-gcc
OBJCOPY=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-objcopy
AS=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-as
AR=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-ar
GDB=$(TOOLCHAIN_PATH)/$(TOOLCHAIN_PREFIX)-gdb

$(BUILD_DIR)/%.o: %.c
    $(CC) $(CFLAGS) $< -c -o $@

all: $(OBJ)
    $(AS) -o $(ASRC:%.s=$(BUILD_DIR)/%.o) $(STARTUP)/$(ASRC)
    $(CC) -o $(BIN_DIR)/$(TARGET).elf $(LDFLAGS) $(OBJ) $(ASRC:%.s=$(BUILD_DIR)/%.o) $(LDLIBS)
    $(OBJCOPY) -O ihex $(BIN_DIR)/$(TARGET).elf $(BIN_DIR)/$(TARGET).hex
    $(OBJCOPY) -O binary $(BIN_DIR)/$(TARGET).elf $(BIN_DIR)/$(TARGET).bin

我修改了FreeRTOS演示项目文件夹CORTEX_M4F_STM32F407ZG-SK中的项目(删除现有任务并创建自己的任务)。这是主要功能:

int main(void) {
    int ret;
    prvSetupHardware();
    DebugPrintf("FreeRTOS v7.3.0 starting\n");
    ret = xTaskCreate(SampleTask0, (signed char *) "T0", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
    if (ret == pdTRUE) {
        DebugPrintf("Task %x creared successfully:%d.\n", SampleTask0, ret);
    } else {
        DebugPrintf("Task 0 created failed.\n");
    }
    ret = xTaskCreate(SampleTask1, (signed char *) "T1", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
    if (ret == pdTRUE) {
        DebugPrintf("Task %x creared successfully:%d.\n", SampleTask1, ret);
    } else {
        DebugPrintf("Task 1 created failed.\n");
    }
    DebugPrintf("Starting scheduler...\n");
    vTaskStartScheduler();
    for (;;);
}

我在FreeRTOSConfig.h中将configMINIMAL_STACK_SIZE配置为4096,并且代码在Task Scheduler启动时运行良好,并调用了我的SampleTask0函数。这是任务代码:

void SampleTask0(void *pvParameters) {
    (void) pvParameters;
    uint16_t delay;
    for (;;) {
        delay = 10000;
        DebugPrintf("Task 0 running\n");
        while(delay) {delay--;}
    }
    vTaskDelete(NULL);
}

任务1功能与任务0几乎相同,只是它打印不同的信息。 这些代码编译,在我将二进制文件写入电路板后,SampleTask0无法按预期工作。通过USART3发送字符的DebugPrintf函数只打印“Tas”,然后一切都停止。我用gdb跟踪代码并逐步执行代码,“Task 0 running”被打印但是当它返回到任务函数时(在“while(delay){delay--;}”之前)发生了错误:

无法访问地址0xa5a5a5a5

的内存

main.c的SampleTask0(pvParameters = 0x0)...

根据FreeRTOS documents,每个任务的堆栈在创建时填充0xa5个字节。我认为堆栈可能有问题。我已将configCHECK_FOR_STACK_OVERFLOW设置为2以启用堆栈溢出检测,但发生这种情况时未调用我的钩子函数。

CORTEX_M4F_STM32F407ZG-SK中的startup_stm32f4xx.s是为EWARM工具链创建的,我将其替换为ST网站下载的STM32F4-Discovery_FW_V1.1.0中的启动文件。所以它可能会破坏堆栈,但我不确定这一点。有人有这方面的想法吗?

1 个答案:

答案 0 :(得分:0)

这个顶部的线程存档在这里:自上次存档快照以来的任何其他信息都可以在实时FreeRTOS支持论坛上找到。 http://www.freertos.org/FreeRTOS_Support_Forum_Archive/February_2013/freertos_FreeRTOS_stack_corruption_on_STM32F4_with_gcc_6772412.html