FreeRTOS는 여러 모로 한물 간 OS이다. mcu의 컴퓨팅 속도가 너무나도 좋아지고, 자동차에서는 AUTOSAR OS가 표준으로 적용되어서 쓸 데가 없다. 하지만 임베디드 디바이스에서 스케줄러를 간단하게 구현할 수 있고, 무엇보다 아직 방산 산업 분야와 같이 진짜로 실시간성이 중요한 경우에는 많이 쓰이고 있다. 예를 들어 LIG넥스원의 Job Description을 보면,

위와 같이 FREE RTOS 가능자를 선호하는 걸 알 수 있다. 그럼 ST사의 mcu 를 이용해서 freeRTOS를 공부해보자. FreeRTOS는 오픈소스라서 미들웨어 형태로 포팅해서 사용할 수 있다.
우선 우리의 친구 STM32CUBEMX를 사용한다면 기본 peripheral 설정을 알아서 해준다.


Yes 눌러 주면 다음과 같은 화면이 나오는데,

기본 세팅이 잘 되어 있다. USART_TX RX 가 기본 세팅되어 있기 때문에 putty로 출력할 수 있고, TCK/TMS로 ST LINK 디버깅 가능하며, Blue Button과 LED2(초록색 LED)에 대해 기본적인 GPIO 세팅이 되어 있다.

여기서 추가로 Middlewares -> FREERTOS -> Interface를 CMSIS_V1으로 설정해 주자. 이러면 CMSIS가 제공하는 API를 사용해서 FreeRTOS 메소드들을 실행할 수 있다.
여기에 중요한 설정이 추가된다. 바로 System Tick을 바꿔줘야 한다.System Core -> SYS ->Timbase Source를 TIMx 로 바꿔준다. TIM은 ST사에서 제공하는 하드웨어 타이머이다. 소프트웨어가 아니라, 하드웨어에 의한 카운터 회로가 돌아가는 녀석이기 때문에, SW에서의 오버헤드 문제에서 벗어나 "정확한" 시간계산이 가능하다.

이제 STM32CUBEIDE를 타겟으로 해서 generate code 눌러주면 세팅 완료다.


실행하면 위와 같이 freertos.c 가 잘 포함됨을 볼 수 있다.
이제 마지막으로 UART를 위한 printf() 함수를 만들어 보자.

stdio.h include한 후에 putchar() 함수만 바꿔주면 된다. Private user code ... 아래에 넣어준다.
int __io_putchar(int ch){
HAL_UART_Transmit(&huart2, &ch, 1, 1000); // 각자 등록한 USARTx에 맞출것
return ch;
}
자 이제 테스트를 해보자. 이때 필자처럼 아무 배경 지식 없이 while(1) 안에 printf하면 아무것도 안나올 것이다.
osKernelStart() 함수가 실행되면 이후 모든 main 함수의 line들은 실행되지 않고,
osKernelStart() -> vTaskStartScheduler() 가 실행되어 FreeRTOS 커널이 스케줄링을 하기 때문에, while(1) 안의 코드는 실행되지 않는다.
따라서 해결책은 osKernelStart() 전에 printf()해보는 것이다.
/* USER CODE END RTOS_THREADS */
printf("freeRTOS will start!!\r\n");
/* Start scheduler */
osKernelStart();
이렇게 하고 putty에서 설정을 실행하면 된다. 장치 관리자에서 COM 포트 번호를 찾아서 등록하고, baud rate같은 경우는
.ioc 파일에서 Connectivity -> USARTx -> Parameter Settings 에서 확인 가능하다. 기본값은 115200 bps이며 안좋은 mcu라면 9600일수도있다.


이제 실행하면,

출력이 잘 된다. 다음 포스트부터는 본격적인 FreeRTOS API에 대해 공부해보자.
'Embedded SW > FreeRTOS' 카테고리의 다른 글
[FreeRTOS] 1. FreeRTOS Task 관련 API(1) (0) | 2025.04.01 |
---|
FreeRTOS는 여러 모로 한물 간 OS이다. mcu의 컴퓨팅 속도가 너무나도 좋아지고, 자동차에서는 AUTOSAR OS가 표준으로 적용되어서 쓸 데가 없다. 하지만 임베디드 디바이스에서 스케줄러를 간단하게 구현할 수 있고, 무엇보다 아직 방산 산업 분야와 같이 진짜로 실시간성이 중요한 경우에는 많이 쓰이고 있다. 예를 들어 LIG넥스원의 Job Description을 보면,

위와 같이 FREE RTOS 가능자를 선호하는 걸 알 수 있다. 그럼 ST사의 mcu 를 이용해서 freeRTOS를 공부해보자. FreeRTOS는 오픈소스라서 미들웨어 형태로 포팅해서 사용할 수 있다.
우선 우리의 친구 STM32CUBEMX를 사용한다면 기본 peripheral 설정을 알아서 해준다.


Yes 눌러 주면 다음과 같은 화면이 나오는데,

기본 세팅이 잘 되어 있다. USART_TX RX 가 기본 세팅되어 있기 때문에 putty로 출력할 수 있고, TCK/TMS로 ST LINK 디버깅 가능하며, Blue Button과 LED2(초록색 LED)에 대해 기본적인 GPIO 세팅이 되어 있다.

여기서 추가로 Middlewares -> FREERTOS -> Interface를 CMSIS_V1으로 설정해 주자. 이러면 CMSIS가 제공하는 API를 사용해서 FreeRTOS 메소드들을 실행할 수 있다.
여기에 중요한 설정이 추가된다. 바로 System Tick을 바꿔줘야 한다.System Core -> SYS ->Timbase Source를 TIMx 로 바꿔준다. TIM은 ST사에서 제공하는 하드웨어 타이머이다. 소프트웨어가 아니라, 하드웨어에 의한 카운터 회로가 돌아가는 녀석이기 때문에, SW에서의 오버헤드 문제에서 벗어나 "정확한" 시간계산이 가능하다.

이제 STM32CUBEIDE를 타겟으로 해서 generate code 눌러주면 세팅 완료다.


실행하면 위와 같이 freertos.c 가 잘 포함됨을 볼 수 있다.
이제 마지막으로 UART를 위한 printf() 함수를 만들어 보자.

stdio.h include한 후에 putchar() 함수만 바꿔주면 된다. Private user code ... 아래에 넣어준다.
int __io_putchar(int ch){
HAL_UART_Transmit(&huart2, &ch, 1, 1000); // 각자 등록한 USARTx에 맞출것
return ch;
}
자 이제 테스트를 해보자. 이때 필자처럼 아무 배경 지식 없이 while(1) 안에 printf하면 아무것도 안나올 것이다.
osKernelStart() 함수가 실행되면 이후 모든 main 함수의 line들은 실행되지 않고,
osKernelStart() -> vTaskStartScheduler() 가 실행되어 FreeRTOS 커널이 스케줄링을 하기 때문에, while(1) 안의 코드는 실행되지 않는다.
따라서 해결책은 osKernelStart() 전에 printf()해보는 것이다.
/* USER CODE END RTOS_THREADS */
printf("freeRTOS will start!!\r\n");
/* Start scheduler */
osKernelStart();
이렇게 하고 putty에서 설정을 실행하면 된다. 장치 관리자에서 COM 포트 번호를 찾아서 등록하고, baud rate같은 경우는
.ioc 파일에서 Connectivity -> USARTx -> Parameter Settings 에서 확인 가능하다. 기본값은 115200 bps이며 안좋은 mcu라면 9600일수도있다.


이제 실행하면,

출력이 잘 된다. 다음 포스트부터는 본격적인 FreeRTOS API에 대해 공부해보자.
'Embedded SW > FreeRTOS' 카테고리의 다른 글
[FreeRTOS] 1. FreeRTOS Task 관련 API(1) (0) | 2025.04.01 |
---|