FreeRTOS быстрый старт на STM32 F4 DISCOVERY

FreeRTOS - операционная система реального времени. Скорее всего если вам нужна операционка на вашем микроконтроллере,  то вы воспользуетесь ей ;) ИМХО
Дотстоинства: бесплатно, быстро, порты под многие архитектуры (не придётся осваивать чтото заново)
Недостатки(ок): документация распространяется платно.. Но не беда! Есть куча сайтов на эту тематику, в том числе и на русском языке.

О том что будет в этой статье: рассказ о том как скомпилировать и запустить FreeRTOS на камне STM32. Запустим 2 задачи, поморгаем светодиодами.

Сперва конечно же качаем FreeRTOS. Это можно сделать с официального сайта ОС freertos.org
В полученном архиве вы найдёте исходники в папке Source и примеры в папке Demo
Идём в папку Source.
Сразу оговорюсь, что я работаю в Eclipse на Ubuntu linux, что говорит о том, что у меня gcc компилятор ;)
В папке с исходниками видим папку Include с заголовочными файлами системы, и папку portable, в которой храняться порты для разных архитектур. Из этой папки скопируем нужные файлы, остально удалим.
Заходим в FreeRTOSV7.1.1/Source/portable/GCC/ARM_CM4F
и копируем оттуда два файла port.c и portmacro.h. Соответственно исходник перемещаем в папку Source, а заголовочный файл в папку Source/Include
Теперь из папки MemMang копируем файл heap_2.c в каталог с исходниками.
После проделанного можно удалить папку portable.

Готово. Дистрибутив приготовили. Теперь настроечный файл FreeRTOSConfig.h. Я не буду толком на нём останавливаться, собственно тут и происходит настройка. Но это дело отдельной статьи. Оговорюсь только о параметре:

configCPU_CLOCK_HZ - частота камня в герцах.

Также нужно переименовать или переназначить прерывания, чтобы ОС их понимала:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler

Файл целиком:

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler<
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler
#define configUSE_PREEMPTION            1
#define configUSE_IDLE_HOOK                     0
#define configUSE_TICK_HOOK                         0
#define configCPU_CLOCK_HZ                      ( ( unsigned long ) 168000000 )
#define configTICK_RATE_HZ                      ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES            ( ( unsigned portBASE_TYPE ) 5 )
#define configMINIMAL_STACK_SIZE        ( ( unsigned short ) 120 )
#define configTOTAL_HEAP_SIZE           ( ( size_t ) ( 18 * 1024 ) )
#define configMAX_TASK_NAME_LEN         ( 16 )
#define configUSE_TRACE_FACILITY        0
#define configUSE_16_BIT_TICKS          0
#define configIDLE_SHOULD_YIELD         1
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES           0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define configUSE_MUTEXES                               0
#define configUSE_COUNTING_SEMAPHORES   0
#define configUSE_ALTERNATIVE_API               0
#define configCHECK_FOR_STACK_OVERFLOW  0
#define configUSE_RECURSIVE_MUTEXES             0
#define configQUEUE_REGISTRY_SIZE               0
#define configGENERATE_RUN_TIME_STATS   0

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet                0
#define INCLUDE_uxTaskPriorityGet               0
#define INCLUDE_vTaskDelete                             0
#define INCLUDE_vTaskCleanUpResources   0
#define INCLUDE_vTaskSuspend                    0
#define INCLUDE_vTaskDelayUntil                 0
#define INCLUDE_vTaskDelay                              1
#define INCLUDE_uxTaskGetStackHighWaterMark 0

/* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY                 255
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    191 /* equivalent to 0xb0, or priority 11. */

/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15.  This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
NVIC value of 255. */

#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15

/*-----------------------------------------------------------
 * UART configuration.
 *-----------------------------------------------------------*/
#define configCOM0_RX_BUFFER_LENGTH             128

#define configCOM0_TX_BUFFER_LENGTH             128
#define configCOM1_RX_BUFFER_LENGTH             128

#define configCOM1_TX_BUFFER_LENGTH             128
#endif /* FREERTOS_CONFIG_H */

В файле main.c нашей программы запустим ОС и зададим две равноправные задачи - мигать диодами.

Инклуды:

#include <stm32f4xx.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h>
#include <misc.h>
#include "FreeRTOS.h"
#include "task.h"

Теперь две задачи:

void vTaskLED1(void *pvParameters) {
        for (;;) {
                GPIO_SetBits(GPIOD, GPIO_Pin_12);
                vTaskDelay(500);
                GPIO_ResetBits(GPIOD, GPIO_Pin_12);
                vTaskDelay(500);
        }
}
void vTaskLED2(void *pvParameters) {
        for (;;) {
                GPIO_SetBits(GPIOD, GPIO_Pin_14);
                vTaskDelay(321);
                GPIO_ResetBits(GPIOD, GPIO_Pin_14);
                vTaskDelay(321);
        }
}

В FreeRTOS принято пользоваться венгерской нотацией, так что можете не удивляться суфиксам и префиксам у функция.. Хотя я считаю это полным идеотизмом.
Обратите внимание, что каждая задача FreeRTOS должна принимать указатель на структуру void, таким способом могут быть переданы параметры.

В функции main инициализируем периферию:

  GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

Создаём две задачи:

    xTaskCreate( vTaskLED1, ( signed char * ) "LED1", configMINIMAL_STACK_SIZE, NULL, 2,
                            ( xTaskHandle * ) NULL);

    xTaskCreate( vTaskLED2, ( signed char * ) "LED2", configMINIMAL_STACK_SIZE, NULL, 2,
                            ( xTaskHandle * ) NULL);

Делается это как видите при помощи функции xTaskCreate. Первый параметр - указатель на функцию (её имя), второй - имя процесса (можно сказать, что используется для красоты), затем - минимальный размер стека для функции. потом - параметры (мы ничего не передаём - NULL), предпоследним есть приоритете (2) и последним указатель на xTaskHandl при помощи которого можно в дальнейшем управлять процессами.

Запускаем планировшик задач:

    vTaskStartScheduler();

Собственно и всё. Прерываний у нас нет, поэтому я удалил файлы с прерываниями..
У меня получилось вот так:

arm-none-eabi-size  --format=berkeley stm32_rtos.elf
   text       data        bss        dec        hex    filename

   3304         12      18924      22240       56e0    stm32_rtos.elf

Finished building: stm32_rtos.siz

ps не забываем указать линкеру папки в которых искать хедеры.

Скачать проект.

Просмотров:   32219

Комментарии

ср, 04/17/2013 - 08:31
Rustem Vafin

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 GPIO_Pin_14;
Должно быть GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_14;

ср, 04/24/2013 - 14:05
Mike

Здравствуйте, спасибо за инструкции - все работает! Однако, попытка входа в режим отладки (Ctrl-F5) останавливается на 24%. Выход один - зарыть окно CoIDE. Иными словами - пошаговая отладка прошивки невозможна! Подскажите, если эта проблема не нова, есть ли ее решение? Заранее спасибо!

пн, 05/27/2013 - 15:48
Den

Помогите не могу проэкт откомпилить, все делал по вашей инструкции

undefined reference to `GPIO_SetBits' main.c /1 line 27 C/C++ Problem
undefined reference to `GPIO_ResetBits' main.c /1 line 20 C/C++ Problem
undefined reference to `GPIO_Init' main.c /1 line 41 C/C++ Problem
undefined reference to `RCC_AHB1PeriphClockCmd' main.c /1 line 37 C/C++ Problem
undefined reference to `GPIO_SetBits' main.c /1 line 18 C/C++ Problem
undefined reference to `GPIO_ResetBits' main.c /1 line 29 C/C++ Problem
control reaches end of non-void function [-Wreturn-type] main.c /1 line 51 C/C++ Problem

вт, 05/28/2013 - 15:06

Эти ошибки уже убрал, возникли другие 

16:06:23 **** Incremental Build of configuration Release for project stm32 ****
make all
make: *** No rule to make target `stm32.elf', needed by `all'. Stop.

16:06:23 Build Finished (took 360ms)

вт, 05/28/2013 - 10:17

вы скачали мой? или создаёте свой?

вт, 05/28/2013 - 15:09

Скачал ваш и по подобию свой сделал, у меня камень stm32F207VGT6, эклипс последняя версия под win Xp 

ср, 05/29/2013 - 17:22

Сбросте проект мне на почту mr.dimas@meta.ua может чего насмотрю.

пт, 02/07/2014 - 19:47
matrixd

Если у кого-то проблемы с компиляцией и вылезают вот эти ошибки:
Error: selected processor does not support Thumb mode `vstmdbeq r0!,{s16-s31}'
Error: instruction not allowed in IT block -- `stmdb r0!,{r14}'
Error: selected processor does not support Thumb mode `vldmiaeq r0!,{s16-s31}'
Error: instruction not allowed in IT block -- `ldmia r0!,{r4-r11}'

Скорее всего неправильно поставлен 1 флаг -mfloat-abi=soft вместо -mfloat-abi=softfp
Вот с такими флагами собираеться на ура:
-mcpu=cortex-m4 -mthumb -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections

Если что у меня stm32f401 discovery

чт, 08/20/2015 - 08:47

Здравствуйте!
Такой вопрос. Данная сборка пошла на ура, спасибо!
Однако пытался собрать новую версию 8.2 в CooCOX. Всё собралось, но при отключении питания программа запускается только после сброса (reset). Автор написал, что удалил файлы с прерываниями. Может, в этом дело. И как это исправить?
Спасибо!

чт, 08/20/2015 - 13:07

Проблема решилась редактирование параметров файла FreeRTOSConfig.h:
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 18 * 1024 ) )
//#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

Добавить комментарий

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и параграфы переносятся автоматически.
CAPTCHA
Введи эти символы. Ато роботы одолели!