먼저 CubeMX를 이용해서 STM32F4 Discovery 보드 환경설정을 해준다.
https://www.youtube.com/watch?v=CsMUmFLNTok&list=LLnJ3dJnBdwC2gZZdKionReg&index=4&t=169s
다음의 영상을 보면 FreeRTOS 코드를 다운로드해서 따로 설정하지 않아도 MiddleWare로 바로 FreeRTOS를 껴넣을 수있다. 최근에는 FreeRTOS CMSIS_V2 도 사용 할 수 있게 되었는데 더 좋은 성능을 내는 것 같다. 하지만 교육영상에서는 V1을 사용했으므로 V1으로 설정해주자.
Create Task
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void Led_GateKeeper(void *pvParameters)
{
TickType_t xDelay = 500 / portTICK_PERIOD_MS;
for(;;)
{
HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin, GPIO_PIN_RESET);
vTaskDelay(xDelay);
HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin, GPIO_PIN_SET);
vTaskDelay(xDelay);
}
}
/* USER CODE END 0 */
int main(void)
{
...
...
/* USER CODE BEGIN 2 */
xTaskCreate(Led_GateKeeper, //Task Pointer
(const char* const)"led_gate", //Task Name
configMINIMAL_STACK_SIZE, //Stack Depth , Task에서 printf 문을 사용할 때 HardFault 에러가 날 수 있다. 이때는 Stack Depth를 더 많이 줘야 한다.
0, //Parameters to pass to task
2, //Task Priority
0); //Pass Handle to created task
/* USER CODE END 2 */
...
/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
vTaskStartScheduler(); //이 부분도 꼭 써주자.
/* USER CODE END RTOS_THREADS */
/* Start scheduler */
osKernelStart();
.....
Delete Task
TaskHandle_t Led_GateKeeperHandle = NULL;
void Led_GateKeeper(void *pvParameters)
{
int count = (int*) pvParameters;
//TickType_t xDelay = 1000 / portTICK_PERIOD_MS;
TickType_t xDelay = pdMS_TO_TICKS(1000);
TickType_t myLastUnblock;
myLastUnblock = xTaskGetTickCount();
for(;;)
{
HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin, GPIO_PIN_RESET);
//vTaskDelay(xDelay); //ms가 아닌 number of ticks, (the number of CPU takes that the kernel runs on)
FreeRTOSConfig.h 에서
#define configTICK_RATE_HZ ((TickType_t)1000) 로 설정했다면 1000Hz이므로 1Tick은
0.001 sec 즉 1msec가 된다. TickType_t xDelay = pdMS_TO_TICKS(1000); 의 의미는 configTICK_RATE_HZ에 상관없이
넘겨주는 parameter (msec) 만큼 xDelay를 해준다라는 의미이다.
ex) TickType_t xDelay = pdMS_TO_TICKS(2000); 이면 configTICK_RATE_HZ가 1000이던 5000이던 상관없이
2초간 Delay 해준다는 뜻.
vTaskDelayUntil( &myLastUnblock, xDelay );
//vTaskDelay 보다 더 안정적인 Delay 함수 사용하려면 FreeRTOSConfig.h 에서 #define INCLUDE_vTaskDelayUntil 1 으로 설정해줘야 함
HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin, GPIO_PIN_SET);
//vTaskDelay(xDelay);
vTaskDelayUntil( &myLastUnblock, xDelay );
if(count == 12){ vTaskDelete(Led_GateKeeperHandle); //Handler 반환 }
count++;
}
}
int main(void)
{
...
/* USER CODE BEGIN 2 */
int pass = 8; //Task에 건네 줄 parameter
//printf("count : %d\r\n", pass);
xTaskCreate(Led_GateKeeper, //Task Pointer
(const char* const)"led_gate", //Task Name
configMINIMAL_STACK_SIZE + 200, //Stack Depth
(void *)pass, //Parameters to pass to task
2, //Task Priority
&Led_GateKeeperHandle); //Pass Handle to created task
/* USER CODE END 2 */
//이 때 Task가 2개인 상태에서 1개의 Task가 Delay에 들어가면 남은 Task들중 priority가 제일 높은 Task가 실행된다.
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128); //CubeMX가 만들어주는 코드
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL); //CubeMX가 만들어주는 코드
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
vTaskStartScheduler();
/* USER CODE END RTOS_THREADS */
/* Start scheduler */
osKernelStart();
'FreeRTOS > FreeRTOS 기본 학습' 카테고리의 다른 글
06 FreeRTOS Tutorial: Handling Interrupt (0) | 2019.06.20 |
---|---|
STM32F4 Discovery board - Keil 5 IDE with CubeMX: Tutorial 8 UART - Updated Dec 2017 (0) | 2019.06.10 |
FreeRTOS API (0) | 2019.06.10 |
Suspending and Resuming task (0) | 2019.06.07 |
FreeRTOS Setup (0) | 2019.06.05 |