STM32 с нуля. FreeRTOS. Обзор и установка операционной системы.

При разработке электронных устройств до поры до времени (иногда довольно долго 🙂 ) удается обходиться без использования операционной системы. Но наступает момент, когда разрабатываемый девайс должен выполнять огромное количество различных функций или, например, должен обеспечивать возможность добавления новой задачи позднее. В этих случаях обойтись без RTOS (операционная система реального времени, ОСРВ) становится невозможно. Как раз про RTOS эта статья, а точнее про ее установку и использование для микроконтроллеров STM32.

Сразу скажу, что я остановил свой выбор на FreeRTOS – эта ОСРВ портирована на огромное количество архитектур, что является, безусловно, большим плюсом. Есть в сети очень хороший мануал на русском языке, там правда очень много букв, но зато все описано максимально подробно и понятно 🙂

Итак, в чем же кроется основная идея ОСРВ?

Операционная система реального времени позволяет организовать множество разнообразных задач и обеспечивает их поочередное выполнение, при этом учитывает приоритет каждой задачи. Также благодаря RTOS можно замутить запуск какой-либо задачи через определенные промежутки времени (причем обеспечивается высокая точность временных интервалов). Задачи могут обмениваться информацией друг с другом при помощи реализованной в RTOS очереди. И наконец, при необходимости возможно легким движением руки добавлять все новые и новые задачи. Конечно же, есть и минусы, связанные в основном с тем, что RTOS занимает довольно много памяти. Но эта проблема актуальна скорее для более старых моделей AVR и других контроллеров с небольшими объемами памяти. Так что нас это не будет сильно волновать!

Что можно сказать конкретно про FreeRTOS…

FreeRTOS – операционная система с открытым исходным кодом. Можно абсолютно бесплатно и без проблем скачать ее последнюю версию (что кстати необходимо сделать, поскольку мы скоро перейдем к созданию проекта под FreeRTOS). Написана библиотека на C с наличием небольших ассемблерных вставок. Опять же, очень советую прочитать мануал на нее. Там и про различные типы многозадачности, про ОСРВ в целом, про организацию прерываний FreeRTOS, про разделение процессорного времени между задачами. В общем, почитать стоит! Мы же рассмотрим практические аспекты установки FreeRTOS, естественно по ходу процесса постараюсь по максимуму объяснять, что и зачем делается. Итак, приступаем!

Для начала дружно скачаем FreeRTOS. У меня, например, FreeRTOS v.7.1.0, по-моему, это последняя версия (на момент написания статьи). Копируем папку с FreeRTOS куда-нибудь поближе к проекту. Именно копируем а не вырезаем/вставляем, поскольку сейчас мы будем удалять из нее то, что нам пока не нужно 🙂

Скопировали, продолжаем…

Я создал в папке с проектом пару папок – Header_Files и Source_Files для header’ов и исходников соответственно. Пусть пока, для простоты, все файлы, которые понадобятся для запуска RTOS лежат там.

Заходим в папку FreeRTOSV7.1.0\FreeRTOSV7.1.0\Demo и удаляем оттуда все, кроме папки CORTEX_STM32F103_Keil. Заходим в единственную оставшуюся папку и обращаем наше внимание на файл FreeRTOSConfig.h. Копируем его в папку header’ов. В общем, я положил его в STMProjects\FreeRTOS\Header_Files. Пусть там и живет! Давайте его сразу же и отредактируем. Открываем и копируем в этот файл следующие строки:

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

Давайте разбираться, что мы сделали. А всего лишь переопределили обработчики прерываний для того, чтобы прерывания из FreeRTOS попали в вектор прерываний. Вот и все!

Папка FreeRTOSV7.1.0\FreeRTOSV7.1.0\Source – копируем из нее все .c файлы в STMProjects\FreeRTOS\Source_Files. Аналогично, файлы из FreeRTOSV7.1.0\FreeRTOSV7.1.0\Source\include помещаем в STMProjects\FreeRTOS\Header_Files.

Теперь проследуем в FreeRTOSV7.1.0\FreeRTOSV7.1.0\Source\portable и там прямо манит папка под названием Keil. Заходим и видим “Nothing to see here”. Первая мысль – “Как же так?…”. Но не отчаиваемся, нам намекают посмотреть папку RVDS – заходим в нее, выбираем наше ядро (папка ARM_CM3) и забираем оттуда два файла к нам в проект.

Осталось зайти в папку FreeRTOSV7.1.0\Source\portable\MemMang и скопировать файл heap_2.c. Все файлы собрали, создаем новый проект в Keil и приступаем ко второй части Мерлезонского балета 🙂

Теперь нам нужно добавить все файлы в проект – это и CMSIS, и SPL, и FreeRTOS:

FreeRTOS создание проекта.

Теперь в настройках проекта прописываем все пути к файлам, присутствующим в проекте, а также не забываем про USE_STDPERIPH_DRIVER:

Настройка Keil.

Теперь напишем пример! Давайте сделаем традиционное мигание диодом, но уже с использованием ОСРВ. Для начала надо подключить файлы:

#include "task.h"
#include "queue.h"
#include "FreeRTOS.h"
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

Теперь надо настроить нужный нам вывод, на который мы повесим светодиод. Кстати, в мануале на FreeRTOS есть еще и правила, в соответствии с которыми рекомендуется оформлять код:

void vFreeRTOSInitAll()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_StructInit(&port);
	port.GPIO_Mode = GPIO_Mode_Out_PP;
	port.GPIO_Pin = GPIO_Pin_0;
	port.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &port);
}

Тут все как обычно, включили тактирование, настроили вывод. Двигаемся дальше:

void vLedTask (void *pvParameters)
{
	while(1)
	{
		if (state == 0)
		{
			GPIO_SetBits(GPIOA,GPIO_Pin_0);
			state = 1;
		}
		else
		{
			GPIO_ResetBits(GPIOA,GPIO_Pin_0);
			state = 0;
		}
	}
	
	vTaskDelete(NULL); 
}

Это задача, которую мы будем выполнять. Тут реализовано, собственно, мигание диодом. В конце функции, за пределами цикла, принято вызывать функцию vTaskDelete(NULL), которая удалит задачу в случае выхода из бесконечного цикла.

Теперь осталось только реализовать функцию main():

int main()
{
	vFreeRTOSInitAll();
	xTaskCreate(vLedTask,(signed char*)"LedTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
	vTaskStartScheduler();
}

Сначала вызываем функцию для конфигурирования вывода PA0. А вот дальше интереснее – создаем задачу при помощи функции xTaskCreate(). Рассмотрим этот момент подробнее. Функция принимает аргументы:

  • pvTaskCode — указатель на функцию, реализующую задачу
  • pcName — нуль-терминальная (заканчивающаяся нулем) строка, определяющая имя функции
  • usStackDepth — глубина (размер) собственного стека создаваемой задачи, в данном случае мы используем минимально допустимый размер стека, определенный макросом configMINIMAL_STACK_SIZE
  • pvParameters— произвольный параметр, передаваемый задаче при ее создании
  • uxPriority — определяет приоритет создаваемой задачи, мы берем tskIDLE_PRIORITY + 1 = (приоритет задачи бездействие) + 1
  • pxCreatedTask — может использоваться для получения дескриптора (handle) создаваемой задачи, который помещается по адресу pxCreatedTask после успешного создания задачи.

Остается в функции main() вызвать планировщика, и все, готово!

Запускаем отладчик и смотрим, что из всего этого вышло. Открываем окошко логического анализатора и настраиваем его на мониторинг вывода РА0 (про это написано в предыдущих статьях по STM32, вот тут, например). Запускаем программу:

Работа программа с FreeRTOS.

Ура, диод мигает!

Подведем итог. Мы установили FreeRTOS, разобрались с ее работой и даже создали небольшую программку с применением ОСРВ. В следующей статье тоже будем писать под FreeRTOS, но это будет что-нибудь посложнее и поинтереснее 🙂

P. S. Вот, кстати, хорошее описание FreeRTOS на русском – ссылка.

Поделиться!

Подписаться
Уведомление о
guest
49 Комментарий
старее
новее большинство голосов
Inline Feedbacks
View all comments
barteroff
barteroff
7 лет назад

Спасибо за FreeRTOS, если не сложно поделитель ссылочкой на подробный мануал по этой ОС.

Dimon
Dimon
7 лет назад

Отличий мануал!
Не подскажите какой размер получился этого примера?

Nemo
Nemo
7 лет назад

Собираетесь ли Вы написать статью FreeRTOS + прерывания?

Очень интересно…Например сейчас создаю драйвер для ультр.зв. сенсора HS-SR04, там информация зашифрована в временных интервалах, и чтобы нормально работать думаю использовать внешние прерывания (ловля начала и окончания импульса)

Марина
Марина
6 лет назад

на картинке с деревом проекта нет heap_2.c ,Без него не видит vPortFree и еще одно имя

INA
INA
6 лет назад

Очень хорошая статья. Большое спасибо!
Есть одна просьба: при создании проекта точно по описанию в статье компилятор ругается на “state” и “port”. Последний решается вставкой кода GPIO_InitTypeDef port в самом начале функции void vFreeRTOSInitAll() , а вот как победить “state” что-то не нашёл.

INA
INA
6 лет назад

Просто я думал, что state имеет отношение к FreeRTOS. Как-то относится непосредственно к ОСРВ. Первый раз занимаюсь сборкой ОСРВ, поэтому “придираюсь” к каждой мелочи. 🙂

INA
INA
6 лет назад

Пробовал собрать FreeRTOS 7.5 для STM32F407, но что-то не получается. Очень много ошибок выдаёт линкёр. Вот такого плана:
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol pxCurrentTCB (referred from port.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol vTaskSwitchContext (referred from port.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol xTaskIncrementTick (referred from port.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol vTaskSuspendAll (referred from timers.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol xTaskGenericCreate (referred from timers.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol xTaskGetSchedulerState (referred from timers.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol xTaskGetTickCount (referred from timers.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol xTaskResumeAll (referred from timers.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol vApplicationMallocFailedHook (referred from heap_2.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol vTaskMissedYield (referred from queue.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol vTaskPlaceOnEventList (referred from queue.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol vTaskPlaceOnEventListRestricted (referred from queue.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol vTaskPriorityDisinherit (referred from queue.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol vTaskPriorityInherit (referred from queue.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol vTaskSetTimeOutState (referred from queue.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol xTaskCheckForTimeOut (referred from queue.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol xTaskGetCurrentTaskHandle (referred from queue.o).
.\Release\test_mka1.axf: Error: L6218E: Undefined symbol xTaskRemoveFromEventList (referred from queue.o).

Сам файл main.c пока пустой, есть только инклюды. Никак не могу понять, что ему не нравится. 🙁

INA
INA
6 лет назад

Все файлы подключил к проекту, все пути указал… Не пойму, что ему надо?… Кейл пятый поставил, хотя и в предыдущем не получалось собрать ОСРВ для STM32F4. Мне нужно именно с F4 поработать, а получается какая-то фигня. Опыта мало, не могу понять в каком направлении копать.

INA
INA
6 лет назад

Был бы очень благодарен Вам. Очень трудно найти ошибку, если на неё указывает линкёр (по крайней мере мне). С STM32 занимаюсь всего неделю и всех хитростей пока не знаю.

INA
INA
6 лет назад

Всё, с установкой, вроде как разобрался. Установил FreeRTOS на STM32F407IG. Просто нужно было уделить особое внимание файлу FreeRTOSConfig.h – от него очень много зависит.
Теперь хочу подключить ENC28J60 и модули RS232 и RS485. Надеюсь, не будет больших проблем с решением этой задачи. 🙂

INA
INA
6 лет назад

Тем не менее, ещё раз спасибо! Из Вашей статьи узнал важные моменты насчёт создания функций (пустых), на отсутствие которых ругался линкёр. Это очень важная для меня информация.
Ещё раз большое спасибо!

Alex
Alex
6 лет назад

Большое спасибо за Ваш труд, в результате которого появилась серия статей, помогающих в освоении STM32. Также как у INA, при создании проекта точно по описанию в статье компилятор ругался на «state» и «port». Благодаря комментариям внес исправления, но появилась другая проблемка, которую самостоятельно решить не получается:
STMProjects\FreeRTOS\Sourse_Files\FreeRTOS1.c: 1 warning, 0 errors
linking…
.\start.axf: Error: L6200E: Symbol __ARM_use_no_argv multiply defined (by freertos1.o and test.o).
.\start.axf: Error: L6200E: Symbol main multiply defined (by freertos1.o and test.o).
Not enough information to list image symbols.
Not enough information to list the image map.
Finished: 2 information, 0 warning and 2 error messages.
“.\start.axf” – 2 Error(s), 1 Warning(s).
Target not created

Игорь
Игорь
6 лет назад

Статья хорошая, но проект в кейле собираться не желает…

.\Header_Files\stm32f10x_type.h(27): error: #256: invalid redeclaration of type name “s32” (declared at line 487 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(31): error: #256: invalid redeclaration of type name “vs32” (declared at line 495 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(35): error: #256: invalid redeclaration of type name “u32” (declared at line 503 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(39): error: #256: invalid redeclaration of type name “uc32” (declared at line 507 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(43): error: #256: invalid redeclaration of type name “vu32” (declared at line 511 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(47): error: #256: invalid redeclaration of type name “vuc32” (declared at line 515 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(53): error: #101: “RESET” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(53): error: #101: “SET” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(53): error: #256: invalid redeclaration of type name “FlagStatus” (declared at line 519 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(53): error: #256: invalid redeclaration of type name “ITStatus” (declared at line 519 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(55): error: #101: “DISABLE” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(55): error: #101: “ENABLE” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(55): error: #256: invalid redeclaration of type name “FunctionalState” (declared at line 521 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(56): warning: #47-D: incompatible redefinition of macro “IS_FUNCTIONAL_STATE” (declared at line 522 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(58): error: #101: “ERROR” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(58): error: #101: “SUCCESS” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(58): error: #256: invalid redeclaration of type name “ErrorStatus” (declared at line 524 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_conf.h(111): warning: #47-D: incompatible redefinition of macro “HSE_Value” (declared at line 528 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(273): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(338): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(357): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(383): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(404): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(568): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(612): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(638): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(664): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(703): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(731): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(770): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(832): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(865): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(882): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(896): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1067): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1098): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1129): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1188): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1219): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1240): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1253): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1285): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1332): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1406): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_rcc.c(1451): warning: #223-D: function “assert_param” declared implicitly
compiling stm32f10x_gpio.c…
.\Header_Files\stm32f10x_type.h(27): error: #256: invalid redeclaration of type name “s32” (declared at line 487 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(31): error: #256: invalid redeclaration of type name “vs32” (declared at line 495 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(35): error: #256: invalid redeclaration of type name “u32” (declared at line 503 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(39): error: #256: invalid redeclaration of type name “uc32” (declared at line 507 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(43): error: #256: invalid redeclaration of type name “vu32” (declared at line 511 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(47): error: #256: invalid redeclaration of type name “vuc32” (declared at line 515 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(53): error: #101: “RESET” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(53): error: #101: “SET” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(53): error: #256: invalid redeclaration of type name “FlagStatus” (declared at line 519 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(53): error: #256: invalid redeclaration of type name “ITStatus” (declared at line 519 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(55): error: #101: “DISABLE” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(55): error: #101: “ENABLE” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(55): error: #256: invalid redeclaration of type name “FunctionalState” (declared at line 521 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(56): warning: #47-D: incompatible redefinition of macro “IS_FUNCTIONAL_STATE” (declared at line 522 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(58): error: #101: “ERROR” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(58): error: #101: “SUCCESS” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(58): error: #256: invalid redeclaration of type name “ErrorStatus” (declared at line 524 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_conf.h(111): warning: #47-D: incompatible redefinition of macro “HSE_Value” (declared at line 528 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(111): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(178): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(286): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(308): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(324): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(346): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(361): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(377): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(397): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(420): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(437): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(466): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(486): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(554): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(613): warning: #223-D: function “assert_param” declared implicitly
STM32F10x_StdPeriph_Driver\src\stm32f10x_gpio.c(632): warning: #223-D: function “assert_param” declared implicitly
compiling system_stm32f10x.c…
.\Header_Files\stm32f10x_type.h(27): error: #256: invalid redeclaration of type name “s32” (declared at line 487 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(31): error: #256: invalid redeclaration of type name “vs32” (declared at line 495 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(35): error: #256: invalid redeclaration of type name “u32” (declared at line 503 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(39): error: #256: invalid redeclaration of type name “uc32” (declared at line 507 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(43): error: #256: invalid redeclaration of type name “vu32” (declared at line 511 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(47): error: #256: invalid redeclaration of type name “vuc32” (declared at line 515 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(53): error: #101: “RESET” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(53): error: #101: “SET” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(53): error: #256: invalid redeclaration of type name “FlagStatus” (declared at line 519 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(53): error: #256: invalid redeclaration of type name “ITStatus” (declared at line 519 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(55): error: #101: “DISABLE” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(55): error: #101: “ENABLE” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(55): error: #256: invalid redeclaration of type name “FunctionalState” (declared at line 521 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(56): warning: #47-D: incompatible redefinition of macro “IS_FUNCTIONAL_STATE” (declared at line 522 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(58): error: #101: “ERROR” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(58): error: #101: “SUCCESS” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(58): error: #256: invalid redeclaration of type name “ErrorStatus” (declared at line 524 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_conf.h(111): warning: #47-D: incompatible redefinition of macro “HSE_Value” (declared at line 528 of “CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
compiling FreeRTOS1.c…
.\Header_Files\FreeRTOSConfig.h(127): warning: #1-D: last line of file ends without a newline
.\Header_Files\stm32f10x_type.h(27): error: #256: invalid redeclaration of type name “s32” (declared at line 487 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(31): error: #256: invalid redeclaration of type name “vs32” (declared at line 495 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(35): error: #256: invalid redeclaration of type name “u32” (declared at line 503 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(39): error: #256: invalid redeclaration of type name “uc32” (declared at line 507 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(43): error: #256: invalid redeclaration of type name “vu32” (declared at line 511 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(47): error: #256: invalid redeclaration of type name “vuc32” (declared at line 515 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(53): error: #101: “RESET” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(53): error: #101: “SET” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(53): error: #256: invalid redeclaration of type name “FlagStatus” (declared at line 519 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(53): error: #256: invalid redeclaration of type name “ITStatus” (declared at line 519 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(55): error: #101: “DISABLE” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(55): error: #101: “ENABLE” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(55): error: #256: invalid redeclaration of type name “FunctionalState” (declared at line 521 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(56): warning: #47-D: incompatible redefinition of macro “IS_FUNCTIONAL_STATE” (declared at line 522 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_type.h(58): error: #101: “ERROR” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(58): error: #101: “SUCCESS” has already been declared in the current scope
.\Header_Files\stm32f10x_type.h(58): error: #256: invalid redeclaration of type name “ErrorStatus” (declared at line 524 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
.\Header_Files\stm32f10x_conf.h(111): warning: #47-D: incompatible redefinition of macro “HSE_Value” (declared at line 528 of “.\CMSIS\CM3\DeviceSupport\ST\STM32F10x\stm32f10x.h”)
FreeRTOS1.c(11): error: #20: identifier “port” is undefined
FreeRTOS1.c(22): error: #20: identifier “state” is undefined
FreeRTOS1.c(33): warning: #111-D: statement is unreachable
Target not created

Вот так вот ругается…

Игорь
Игорь
6 лет назад

Разобрался. Сделал пустой проект в Кейле по описанию на этом же сайте, потом добавил файлы FreeRTOS к проекту – все собралось без ошибок.

Игорь
Игорь
6 лет назад

Спасибо за статьи! Неплохо было бы выкладывать рабочие проекты к статьям – думаю, это было бы большим плюсом.

LEV
LEV
6 лет назад

Подскажите пожалуйста
патаюсь поморгать диодом т.к. судя по всму не работает функция:
vTaskDelay( 5 / portTICK_RATE_MS );

Возможно необхадимо что либо в FreeRTOSConfig.h подправить что бы использовать эту функцию?

У меня 2 задачи, одна подает напряжание на вывод другая убирает. Если использовать taskYIELD();
в конце каждой задачи то вроде как работает- диод горит тусклее.

LEV
LEV
Reply to  Aveal
6 лет назад

Вот мой код:

*
*
*

void vLedTestSet (void *pvParameters)
{
for (;;)
{
GPIOB->BSRR =GPIO_BSRR_BS5; // Выставили бит 5. GPIO_BSRR_BS5 это битмаска
vTaskDelay( 250 / portTICK_RATE_MS );
//taskYIELD();
}
}

void vLedTestClear (void *pvParameters)
{
for (;;)
{
GPIOB->BSRR =GPIO_BSRR_BR5; // Сбросили бит 5.
vTaskDelay( 250 / portTICK_RATE_MS );
}
}

int main(void)

{
InitAll();
xTaskCreate(vLedTestSet,(signed char*)”LedSet”, configMINIMAL_STACK_SIZE,NULL, tskIDLE_PRIORITY + 1, NULL);
xTaskCreate(vLedTestClear,(signed char*)”LedClear”, configMINIMAL_STACK_SIZE,NULL, tskIDLE_PRIORITY + 1, NULL);

vTaskStartScheduler();

}

может тут я что то не так делаю???

dnsss
6 лет назад

Кажется это отличная статья, но у меня напрочь отказывается собираться проект. Видимо по своей неопытности, я не очень понимаю где то место поближе к проекту и как правильно вырезать на фиг. Не могли бы вы выложить ссылку на проект? много вопросов сразу бы отпало. Спасибо

dnsss
Reply to  Aveal
6 лет назад

Класс! Теперь разобрался. Спасибо

dnsss
6 лет назад

Подскажите, пожалуйста сколько нужно оперативки для использования FreeRTOS? Дело в том, что в самом тупом примере с мигание одного светодиода heap2 сжирает практически весь ее запас (у меня 16КБ)

Module ro code ro data rw data
—— ——- ——- ——-
D:\projects\IAR_ARM\start_discovery\FreeRTOS\Demo\CORTEX_STM32L152_IAR\Debug\Obj: [1]
heap_2.o 300 6 10 264
list.o 152
main.o 316 20 12
port.o 224 4 4
portasm.o 124
queue.o 1 018
startup_stm32l1xx_md.o 476
stm32l1xx_gpio.o 194
stm32l1xx_it.o 18
stm32l1xx_rcc.o 36
system_stm32l1xx.o 368
tasks.o 2 032 12 256
————————————————-
Total: 5 258 42 10 536

не очень наглядный листинг. в общем 10 264 байт уходит под обслуживание heap2. если задачу усложнить, причем довольно существенно – добавляем ip стек с возможностью одновременного подключения 40 клиентов, всякой статистикой и прочим, то heap2 отъедает 16,5КБ. В принципе, считаю это не большим увеличением по сравнению с многократным усложнением программы.
Вот я и спрашиваю, действительно ли heap2 должен по умолчанию съедать столько оперативки? Ведь запускают же как-то FreeRTOS даже на AVR’ках, а так в разы ее меньше. Может нужно настройки какие применить?

dnsss
6 лет назад

Ага, сам сразу и допер. в FreeRTOSConfig.h есть параметр #define configTOTAL_HEAP_SIZE ( ( size_t ) (10 * 1024 ) )
Поставил 5*1024, соответственно размер уменьшился в два раза. все скомпилировалось со всеми стеками и web страничкой. как найду пропавший модуль с enc28, отпишусь заработало ли

Evgeny_s
Evgeny_s
6 лет назад

портировал на F3 и тыкает он меня в это:
RTOS.axf: Error: L6218E: Undefined symbol vTaskStartScheduler (referred from main.o).
RTOS.axf: Error: L6218E: Undefined symbol xTaskGenericCreate (referred from main.o).
где бы я мог накосячить?

innovator_king
innovator_king
6 лет назад

Здравствуйте. Спасибо за ваши труды. Ваши статьи очень помогают по усвоению STM32. Но в данной статье обнаружились ошибки. Использовал Keil 5. Проект не соберётся по двум причинам:
1 – инклуды #include “task.h” и #include “queue.h” должны располагаться под #include “FreeRTOS.h”.
2 – определить переменные GPIO_InitTypeDef port;
uint8_t state;
С уважением, Евгений.

Haamu
Haamu
6 лет назад

Не могли бы Вы дать ссылку на мануал по FreeRTOS, а то та, что в конце статьи, не рабочая.

Василий
Василий
5 лет назад

А с TNKernel не было опыта?

Александр
Александр
5 лет назад

Спасибо! Хорошая статья!
А что делать тем у кого в загруженной FreeRTOS в папке DEMO нет папки CORTEX_STM32F4XX_Keil, а проект хочется запустить именно на чипе из этой серии? Конкретнее есть у меня плата STMF4 Discovery. Хочу на ней поиграться…

илья
илья
4 лет назад

Здравствуйте, реализовал данный пример на stm32f4, при отладке залетает в Default_Handler, подскажите пожалуйста в чём может быть ошибка, проект отправлю на почту. Заранее спасибо.

Присоединяйтесь!

Profile Profile Profile Profile Profile
Vkontakte
Twitter

Язык сайта

Август 2020
Пн Вт Ср Чт Пт Сб Вс
 12
3456789
10111213141516
17181920212223
24252627282930
31  

© 2013-2020 MicroTechnics.ru