Повреждение стека FreeRTOS на STM32F4 с помощью gcc

Я пытаюсь запустить FreeRTOS на моей плате stm32f4discovery. Я установил 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

Я модифицировал проект в папке CORTEX_M4F_STM32F407ZG-SK демонстрационных проектов FreeRTOS (удалив существующие задачи и создав свои собственные). Вот основная функция:

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 (;;);
}

Я сконфигурировал configMINIMAL_STACK_SIZE как 4096 в FreeRTOSConfig.h, и код работает нормально, так как планировщик заданий запустил и вызвал мою функцию 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 не работает должным образом. Функция DebugPrintf, которая отправляет символ через USART3, выводит только «Tas», а затем все останавливается. Я отследил код с помощью gdb и пошагово выполнил код, было напечатано «Задача 0 запущена», но когда она вернулась в функцию задачи (до «while (delay) {delay--;}») произошла ошибка:

Нет доступа к памяти по адресу 0xa5a5a5a5

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

Согласно документам FreeRTOS, при создании стек каждой задачи заполняется байтами 0xa5. Я думаю, что со стеком что-то не так. Я установил для configCHECK_FOR_STACK_OVERFLOW значение 2, чтобы включить обнаружение переполнения стека, но моя функция перехвата не была вызвана, когда это произошло.

Файл startup_stm32f4xx.s в CORTEX_M4F_STM32F407ZG-SK был создан для цепочки инструментов EWARM, и я заменил его файлом запуска в STM32F4-Discovery_FW_V1.1.0, который я загрузил с веб-сайта ST. Таким образом, это может потенциально повредить стек, но я не уверен в этом. У кого-нибудь есть идеи по этому поводу?


person Wang Ye    schedule 19.02.2013    source источник
comment
Попробуйте прокомментировать вызов DebugPrintf и посмотрите, появится ли у вас такая же ошибка. Но я предполагаю, что стек определенно поврежден вызовом DebugPrintf. Вы также можете попробовать изменить размер стека.   -  person Adi    schedule 25.02.2013
comment
Набор инструментов, который я использовал для компиляции кода, не поддерживает libc, поэтому FreeRTOS не может получить доступ к таким функциям, как memset и memcmp. Эта проблема была решена после того, как я реализовал эти функции. Посетите ссылку, предоставленную Ричардом, для получения дополнительной информации.   -  person Wang Ye    schedule 25.02.2013


Ответы (1)


Архив обсуждений наверху находится здесь: любую дополнительную информацию с момента создания последнего снимка архива можно найти на живом форуме поддержки FreeRTOS. http://www.freertos.org/FreeRTOS_Support_Forum_Archive/February_2013/freertos_FreeRTOS_stack_corruption_on_STM32F4_with_gcc_6772412.html

person Richard    schedule 24.02.2013
comment
Я спросил то же самое на форуме FreeRTOS и получил ответы. Теперь этот вопрос решен. - person Wang Ye; 25.02.2013
comment
@ Ван Е: Пожалуйста, предоставьте решение и здесь! - person eDeviser; 30.06.2017