정의
RTOS는 실시간 시스템을 위해 개발된 운영체제로, 멀티태스킹 환경에서 Task 처리시간을 일관되게 유지하기 위한 용도로 사용한다. RTOS는 시분할 시스템 하에서 우선순위 기반 스케줄링을 통해 우선순위가 높은 task가 먼저 작업을 처리할 수 있게 함으로써 구현한다.
참고. 스케줄링 : 프로세스들에게 CPU 등 자원을 배정하는 것을 말함.
설정
Interface는 CMSIS_V2로 선택한다.
CMSIS는 Cortex Microcontroller Software Interface Standard의 약자로 ARM Cortex 시리즈끼리의 호환성 및 이식성 증대를 위해 ARM사에서 정한 소프트웨어를 말한다.
그리고 CMSIS_RTOS 는 ARM사에서 RTOS의 API를 추상화해서 RTOS의 종류가 달라져도 동일한 API로 사용할 수 있도록 제공되는 인터페이스이다.
나머지 Configuration은 그대로 두고 Code Generation을 누르면 다음과 같은 경고창이 뜬다.
나와있는 내용대로 수정해 주자.
SYS에서 Timbase Source를 Systick이 아닌 TIM4로 설정했다.
FreeRTOS Advanced Setting에서 USE_NEWLIB_REENTRANT를 Enable 한다.
다음 Code Generation을 누르면 프로젝트 내에 Middlewares - Third_Party - FreeRTOS 의 소스파일이 들어간 것을 확인할 수 있다.
Main.c
osKernelInitialize() 라는 스케줄러를 초기화하는 함수가 있고 그아래 MX_FREERTOS_Init() 를 따라 들어가보면
아래와 같이 default Task 가 샘플로 생성된 것을 확인할수 있다.
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Private function prototypes -----------------------------------------------*/
//...
void MX_FREERTOS_Init(void) {
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
}
//...
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
/* Private application code --------------------------------------------------*/
이 Task는 CubeMX툴에서 디폴트로 만들어져있던 것이다.
이 아래 default Task 와 같은 속성으로 Task를 두 개 더 만들어 준다.
Code Generation 하면 다음과 같이 코드가 생성된 것을 알 수 있다.
위에서 Task 핸들러를 만들고 Task_attributes 를 통해 속성을 설정해둔다.
osThreadNew 함수를 통해 Task를 위에서 설정한 attributes 대로 생성하며 반환값을 핸들러에 넘긴다.
Task02와 Task03의 내용 수정
void StartTask02(void *argument)
{
/* USER CODE BEGIN StartTask02 */
/* Infinite loop */
for(;;)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);
osDelay(500);
}
/* USER CODE END StartTask02 */
}
//...
void StartTask03(void *argument)
{
/* USER CODE BEGIN StartTask03 */
/* Infinite loop */
for(;;)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
osDelay(200);
}
/* USER CODE END StartTask03 */
}
LED와 연결된 PB0, PB7, PB14 를 GPIO Output으로 잡았다.
참고 : https://www.youtube.com/watch?v=N-dZEJGsA6A
'임베디드 개발 > STM32 (ARM Cortex-M)' 카테고리의 다른 글
STM32 ] Dynamixel AX-12A 모터 제어하기 (1) (7) | 2022.08.11 |
---|---|
STM32 ] FreeRTOS + Semaphore ISR 사용 예제 (0) | 2022.08.08 |
STM32 ] Timer Input Capture 사용하여 PWM 신호 캡쳐하기 (2) | 2022.07.25 |
STM32 ] 자율주행 코드 짜기 - 프로젝트 준비과정 (6) (0) | 2022.07.25 |
STM32 ] SPI 통신 사용하기 (0) | 2022.07.24 |