RTOS 사용
: thread 들이 거의 동시에 동작하면서도(실제로는 CPU가 왔다갔다)
그와중에 진짜 필요한 task는 우선적으로 실행될 수 있도록함 (우선순위)
0. STM32 cubeide > from1.5.0
1. cube32 Folder > Third party > FreeRTOS Folder
2. lib 폴더에 복붙
3.빌드제외
CMSIS V2
portable Folder > gcc, memmang 이외
GCC Folder > ARM_CM3 이외
Mammeng > heap_4 이외
// 정적으로 스택메모리 사용 (static)
4. Include
Include Folder , ARM_CM3, CMSIS_RTOS
5. config.h
config_templete > bsp > config rename
Total_Heap_Size : 6 // 메모리 용량 부족할때
sysTick 을 따로 사용할 경우 Handler 주석처리
SVC, pendSV 따로 사용할 경우 > stm32xx.it.c (자체 it) > 주석처리 (#if 0, endif)
/*
sysTick 을 공유해서 같이 사용 할 경우
: FreeRTOS 에서는 최하위 우선순위
> 더 높은 우선순위에서 Hal_Dealy, getTick 같은 함수를 쓰면 sysTick 이 안걸리고 Hang 발생
// 원래 sysTick 이 계속 돌아가면서 시간 계산 해줘야함
//
- 높은 우선순위 인터럽트 내에서는 HAL_Delay()를 사용하지 않는 것이 원칙
- > FreeRTOS의 vTaskDelay() or 타이머 기능을 사용하는 것이 좋음
FreeRTOS 에서 sysTick 을 최하위로 두는이유
: FreeRTOS > Task scheduling
:: sysTick > 단순히 시간 늘려서 다음 스케쥴링 호출 하는 용도
> USART, CAN :: us 단위로 통신 ( sysTick 보통 ms )
> sysTick 에게 방해받으면 안됨.
6. bsp.h > #include : cmsis_os.h
7. osSysTickHandler > sysTick 에 추가 :: 스케쥴러 호출
> HAL 과 FreeRTOS tick 동기화 > 간단하게 사용 하기위한 용도
>> Porting 완료
1. 쓰레드 선언
static void threadMain(void const *argument);
2. 쓰레드 생성
osThreadDef(threadMain, threadMain, _HW_DEF_RTOS_THREAD_PRI_MAIN, 0, _HW_DEF_RTOS_THREAD_MEM_MAIN);
if (osThreadCreate(osThread(threadMain), NULL) != NULL)
{
logPrintf("threadMain \t\t: OK\r\n");
}
else
{
logPrintf("threadMain \t\t: Fail\r\n");
while(1);
}
osKernelStart();
>> Google : cmsis rtos :: Reference 확인 가능
3. 쓰레드 정의
> 우선순위, 스택메모리 관리
#define _HW_DEF_RTOS_MEM_SIZE(x) ((x)/4)
> 내부를 들여다 보면 쓰레드 사이즈를 잡을때 * sizeof( StackType_t) // uint32_t
> 다시 4를 나누어줌 > byte 단위로 확인
#define _HW_DEF_RTOS_THREAD_PRI_MAIN osPriorityNormal
#define _HW_DEF_RTOS_THREAD_PRI_LED osPriorityNormal
#define _HW_DEF_RTOS_THREAD_MEM_MAIN _HW_DEF_RTOS_MEM_SIZE( 2*1024)
#define _HW_DEF_RTOS_THREAD_MEM_LED _HW_DEF_RTOS_MEM_SIZE( 256)
#define _USE_HW_RTOS
4. main 내에서 oskernelStart > threadMain 이 실행됨
> apMain 이 하나의 쓰레드로서 동작함
static void threadMain(void const *argument)
{
UNUSED(argument);
apMain();
}
5. dalay
스케쥴 실행 > osDelay
아니면 > Hal_Delay
::
HAL_Delay : 쓰레드 실행중에 (계속 점유하면서) 지연시킴
> 같은 우선순위면 몇개씩 실행됨 > 비효율적
osDelay : 지정한 시간만큼 쓰레드 suspend
> 그 시간동안 다른 쓰레드 동작
void delay(uint32_t ms)
{
#ifdef _USE_HW_RTOS
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
osDelay(ms);
}
else
{
HAL_Delay(ms);
}
#else
HAL_Delay(ms);
}
#endif
}
6. 여러개의 쓰레드를 만들어보자 ex) LED
[ ap.c ]
(1) 쓰레드 선언
static void threadLed(void const *argument);
(2) 쓰레드 init
osThreadDef(threadLed, threadLed, _HW_DEF_RTOS_THREAD_PRI_LED, 0, _HW_DEF_RTOS_THREAD_MEM_LED);
if (osThreadCreate(osThread(threadLed), NULL) != NULL)
{
logPrintf("threadLed \t\t: OK\r\n");
}
else
{
logPrintf("threadLed \t\t: Fail\r\n");
while(1);
}
(3) 쓰레드 만들기
void apMain(void)
{
while(1)
{
delay(1);
}
}
static void threadLed(void const *argument)
{
UNUSED(argument);
while(1)
{
ledToggle(_DEF_LED1);
delay(500);
}
}
>> Window > show view > FreeRTOS :: 각종 정보 확인가능