MyTetra Share
Делитесь знаниями!
FreeRTOS. Задачи и приоритеты
Время создания: 23.04.2018 11:03
Раздел: Electronics - Microcontrollers - STM32 - CMSIS

Скачиваем FreeRTOS с официального сайта: www.freertos.org


В проекте создаем одноименную папку с 2 каталогами: inc и src. В них закидываем из скачаной ОС файловое содержимое папок Source и include.

src:


inc:


По поводу файлов port.c и portmacro.h, а так же heap_x.c:

В папке portable находим нужный компилятор (Keil ссылается на папку RVDS), в ней нужный нам камень (в моем случае ARM_CM4F для STM32F407).

Из папки Source/portable/MemMang забираем исполняемый фал того способа работы с памятью, который нам нужен. В данных статьях используется heap_1.c.

В корневом каталоге ОС находим папку Demo, в ней CORTEX_M4F_STM32F407ZG-SK. Оттуда забираем FreeRTOSConfig.h и помещаем его в проектный раздел workspace/code/inc.


В кейле через менеджер подключаем папку FreeRTOS:



+



В main.c прописываем заголовочники:


#include "stm32f4xx.h"

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"


И пытаемся скомпилировать. У меян вылезли ошибки. Решилось костыльным добавлением в файл port.c объявления:


#include "stm32f4xx.h"


и функций в конце файла:


void vApplicationMallocFailedHook( void )

{

while(1){}

}


int vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )

{

( void ) pcTaskName;

( void ) xTask;

while(1){}

}


void vApplicationIdleHook( void ) { }

void vApplicationTickHook( void ) { }


После этого можно допиливать конфиг для РТОС и забивать программу задачами.

Вырезка из конфига:


#define configUSE_PREEMPTION 1

#define configUSE_IDLE_HOOK 1

#define configUSE_TICK_HOOK 0

#define configCPU_CLOCK_HZ ( SystemCoreClock )

#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )

#define configMAX_PRIORITIES ( 5 )

#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 32 )

#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 64 * 1024 ) )

#define configMAX_TASK_NAME_LEN ( 10 )

#define configUSE_TRACE_FACILITY 0

#define configUSE_16_BIT_TICKS 0

#define configIDLE_SHOULD_YIELD 1

#define configUSE_MUTEXES 1

#define configQUEUE_REGISTRY_SIZE 0

#define configCHECK_FOR_STACK_OVERFLOW 2

#define configUSE_RECURSIVE_MUTEXES 1

#define configUSE_MALLOC_FAILED_HOOK 1

#define configUSE_APPLICATION_TASK_TAG 0

#define configUSE_COUNTING_SEMAPHORES 1

#define configGENERATE_RUN_TIME_STATS 0



Полный код:


#include "stm32f4xx.h"

#include "FreeRTOS.h"

#include "task.h"

#include "queue.h"


void RCC_init(void);

void GPIO_init(void);

void vTaskLedArrow(void *argument);

void vTaskLedBlink(void *argument);


int main(void)

{

RCC_init();

GPIO_init();


xTaskCreate(vTaskLedArrow, "Arrow", 32, NULL, 1, NULL);

xTaskCreate(vTaskLedBlink, "Blink", 32, NULL, 1, NULL);

vTaskStartScheduler();

while(1)

{

/*Code Section for Error Indication*/

GPIOD->BSRR |= GPIO_BSRR_BS12;

GPIOD->BSRR |= GPIO_BSRR_BS13;

GPIOD->BSRR |= GPIO_BSRR_BS14;

GPIOD->BSRR |= GPIO_BSRR_BS15;

}

}


void RCC_init(void)

{

RCC->CR |= (RCC_CR_HSEON); //Enable HSE

while( !(RCC->CR & RCC_CR_HSERDY) ) {}; //ready to start HSE


//FLASH

FLASH->ACR |= FLASH_ACR_LATENCY //latency for flash memory

| FLASH_ACR_PRFTEN

| FLASH_ACR_ICEN

| FLASH_ACR_DCEN;

//PLL - HSE

RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSE; //set HSE as PLL source

RCC->CR &= ~(RCC_CR_PLLON); //disable PLL before changes

//PLL M

RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLM); //clear all PLLM bits

RCC->PLLCFGR |= RCC_PLLCFGR_PLLM_2; //set PLLM = 4 (100)


//PLL P

RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLP); //main PLL division PLLP = 2: 00

//PLL N

RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLN); //clear all PLLN bits with mask

RCC->PLLCFGR |= (RCC_PLLCFGR_PLLN_3 //set PLLN = 168 (1010 1000)

| RCC_PLLCFGR_PLLN_5 //for 8 or 16 MHz HSE

| RCC_PLLCFGR_PLLN_7); //

//PLL Q 7 (0111)

RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLQ);

RCC->PLLCFGR |= (RCC_PLLCFGR_PLLQ_0

| RCC_PLLCFGR_PLLQ_2

| RCC_PLLCFGR_PLLQ_2);

//AHB Prescaler

RCC->CFGR &= ~(RCC_CFGR_HPRE); //Prescaler = 1

RCC->CFGR |= RCC_CFGR_HPRE_DIV1; //AHB = SYSCLK/1

//APB1 Prescaler 8

RCC->CFGR &= ~(RCC_CFGR_PPRE1);

RCC->CFGR |= RCC_CFGR_PPRE1_DIV8;

//APB2 Prescaler 2

RCC->CFGR &= ~(RCC_CFGR_PPRE2);

RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

//PLL enable

RCC->CR |= RCC_CR_PLLON; //enalbe PLL

while((RCC->CR & RCC_CR_PLLRDY) == 0) {} //wait for PLL is ready

//PLL System

//RCC->CFGR &= ~RCC_CFGR_SW;

RCC->CFGR |= RCC_CFGR_SW_PLL; //PLL selected as system clock

while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) {} //wait for PLL is used

}


void GPIO_init(void)

{

//RCC

RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; //enable RCC for PortD

//Port D

GPIOD->MODER = 0x55000000; //0b0101.0101 0000.0000 0000.0000 0000.0000

GPIOD->OTYPER = 0; //push-pull enable

GPIOD->OSPEEDR = 0; //low speed

GPIOD->BSRR = 0xF0000000; //turn off all LED

}


void vTaskLedArrow(void *argument)

{

while(1)

{

GPIOD->BSRR |= GPIO_BSRR_BR13;

GPIOD->BSRR |= GPIO_BSRR_BR15;

vTaskDelay(3000); //300 ms

GPIOD->BSRR |= GPIO_BSRR_BS13;

vTaskDelay(3000);

GPIOD->BSRR |= GPIO_BSRR_BS15;

vTaskDelay(3000);

GPIOD->BSRR |= GPIO_BSRR_BR13;

vTaskDelay(3000);

}

}


void vTaskLedBlink(void *argument)

{

while(1)

{

GPIOD->BSRR |= GPIO_BSRR_BS12;

GPIOD->BSRR |= GPIO_BSRR_BS14;

vTaskDelay(2000); //300 ms

GPIOD->BSRR |= GPIO_BSRR_BR12;

GPIOD->BSRR |= GPIO_BSRR_BR14;

vTaskDelay(2000);

}

}



























 
MyTetra Share v.0.53
Яндекс индекс цитирования