1. FreeRTOS 관련정보
FreeRTOS 관련문서
사용하면서 오래전에 Vxworks 나 다른 RTOS가 생각나며 자동으로 비교가 되어지는데, 물론 상용 RTOS에 비교하는 것이 좀 무리일수도 있지만,
무료인 Linux 와 변종 RTLinux 도 있기때문에 비교되어지며, 기능이 부족하다고 생각했으나, 의외로 괜찮은 무료 RTOS인 것 같다.
- ESP32의 FreeRTOS의 Version 확인 (IDFv4.2.2)
ESP32에서 사용하는 FreeRTOS Version v8.2.0기반으로 했으나, 특정함수는 v9.0.0 라고한다
아래를 읽어보면, SMP기반으로 동작한다.
1.1 FreeRTOS의 Config 확인
FreeRTOS의 각 설정으로 모든 API에서 이 설정기준으로 동작하므로 관련설정을 확인하자
- ESP32의 FreeRTOSConfig.h / FreeRTOS.h
ESP32의 경우, FreeRTOSConfig.h가 존재하며, 이는 FreeRTOS.h에 포함되며, 상위와 다르게, 다시 Wrap 해서 CONFIG를 진행
ESP32의 FreeRTOSConfig.h / FreeRTOS.h 파일
일반 FreeRTOSConfig.h 파일
FreeRTOS 관련설정값들로 이 값과 상위값을 비교
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configTICK_RATE_HZ ( CONFIG_FREERTOS_HZ ) //Tick Time 100Hz, Linux 와 동일
#ifdef SMALL_TEST
#define configMAX_PRIORITIES ( 7 )
#else
#define configMAX_PRIORITIES ( 25 ) // 숫자가 높을수록 우선순위가 높음
#endif
.....
#define configAPPLICATION_ALLOCATED_HEAP 1 // Heap 사용여부 결정, heap_1/2 or 4.c 사용시 ucHeap 와 array 와 dimension 사용
#define configTOTAL_HEAP_SIZE (&_heap_end - &_heap_start) // Size를 직접 넣거나, Linker Scirpt에서 설정
//esp32의 heap의 구성 (heap 3으로 추정)
#define configSUPPORT_DYNAMIC_ALLOCATION 1
ESP32의 FreeRTOSConfig.h
FreeRTOS Memory Management (Heap)
ESP32 Memory Management
1.2 FreeRTOS의 Scheduler
Vxworks 처럼 Schduling 알고리즘이 여러 개 존재하여 선택가능할 줄 알았는데, 현재 찾아본 것으로는 없는 것으로 보인다.
기본적으로 운영되어지는 Scheduling 알고리즘을 우선적으로 파악하고 특징을 좀 알아야겠다.
vTaskStartScheduler/vTaskEndScheduler
- FreeRTOS의 우선순위 와 Scheduling 알고리즘
아래글을 읽어보면, 우선순위는 숫자가 높을수록 높으며, Round-Robin이 기본인것 같음
하지만 상위 FreeRTOSConfig.h을 보면 숫자가 높으면, 우선순위가 높다
RTOS이니 선점방식이 지원될 것이며, 처음에 각 Scheduing 알고리즘설정부분이 있을 줄 알았는데, 아직 찾지못함
Real-Time Scheduling
아래의 링크의 그림을 보면 선점방식으로 동작되는 것을 알수 있음 (높이가 우선순위)
RTOS에서 좀 애매한 것은 우선순위에 대한 Queue의 설명이 없음, 추후에 다시 확인
FreeRTOS의 Scheduling 관련개념자료
보통 Priority Queue 관련설명도 같이 해주는데, 그 부분이 없음
1.3 FreeRTOS의 AMP/SMP 방식
ARM용 Multi Core방식소개
오래전에 ARM용 Multi Core 방식을 간단히 정리
- FreeRTOS의 Single-Core 와 Multi-Core 의 RTOS Scheduling
- Single-Core: default
- AMP(asymmetric multicore): multiple kernel multi-core
- SMP(symmetric multicore): one kernel multicore (Linux에서 많이 사용하며 ARM용)
Single Core의 경우 고정된 우선순위 선점 Scheduing 과 Round-Robin의 Time-slicing 방식
한마디로 각각의 우선순위 Level 1 ~ 128 를 만든 후 각각 Level 독자 공간에 Round-Robin 방식으로 돌리는 방식 (Vxworks도 거의 동일)
상위방식으로 하면 우선순위가 높으면 항상 선점되어 돌려지며, 동일한 우선순위는 Round-Robin 방식으로 돌아감
(주의, Scheduler 알고리즘은 Round-Robin 이외 FIFO 등 선택해서 사용하지만, 상위에 언급했듯이, FreeRTOS는 아직 발견못함)
- AMP(asymmetric multicore)
Multi-Core일 경우 사용하며, 비대칭형으로 2개의 경우, 각 Core마다 각 FreeRTOS를 생성구축하며, 중요한 것은 Parrellel Programing 별도로 진행
말이 좀 어려운가?, 간단히 설명해서 각 Core마다 각 Scheduler가 개별존재.
사실 거의 잘 안쓴다.
(하지만, 필요할 경우가 있으며, 각 Core가 독자적으로 각 Scheduler 에 따라 동작하기 원할 경우)
Multi-Core 사용시 가장 일반적으로 사용하는 방식으로 FreeRTOS가 직접 각 Core를 Control하는 방식이며, Linux에서도 많이 사용되어진다.
한 마디로 1개 Scheduler 가 각 여러 Core들을 관리하며 동작하는 방식이다.
FreeRTOS의 Single/AMP/SMP
FreeRTOS의 SMP관련정보
ESP32의 SMP 관련정보
개인적으로 궁금한 것은 Cache는 어떻게 운영이 되는지가 궁금하며, 각자 Cache로 사용하는지 공용 Cache로 사용하는지는 추후 알아보도록하자
Interrupt의 경우도 현재 우선순위가 있는 것로 보아서 Nested Interrupt (중첩 인터럽트) 허용하는 것으로 보인다.
추후 좀 더 자세히 읽고 파악한 후 관련부분 수정
- ESP_INTR_FLAG_IRAM
- ESP_INTR_FLAG_LOWMED
- ESP_INTR_FLAG_HIGH
1.4 FreeRTOS의 API
기본적인 통신방법인 Queue 와 Semahpore 를 좀 알아보도록 하자
처음 Queue 사용하면서 Queue 사이즈를 알 수가 없어 사용하기가 불편하며, 솔직히 잘 구현된 API는 아닌것 같다.
Queue의 Size 문제를 알지 못해 회사지인이 알려주어, 아래 함수로 Queue 사이즈 확인가능하나, 불편하다.
참고로, Counting Semaphore도 제공하며, 상위 Queue도 본인이 원하면, Counting Semaphore로 구현가능하다.
일반 2진 Semaphore 역시 Data Sync용이 아닌 Signal Event 용으로 잘 동작되지가 않는다.
강제로 이진 Semaphore를 내부 값을 0으로 만든 다음 Singal 용으로 Take /Give로 Task를 Control하려고 했는데 아예 동작되지 않는다.
이유는 아래에 별도의 Task용 Semahphore 제공해서 그런거 같다.
(Semaphore 동작은 아주 간단하다 값이 0이되면 Task Blocking 되는 시스템)
재미 있는 것은 ISR용 SemaphoreTake가 있는데, Blocking Time을 허용하지 않는다고 함
Linux Kernel 의 보통 필요할 경우, Spin lock을 사용한다 (Spin lock 과 Semahpore 다름)
즉 Signal 목적으로 사용할 경우 아래 함수로 사용하면 될 것 같다.
지속적으로 관련함수, 즉 API들을 파악 중이지만, 익숙해지는 수 밖에 없는 것으로 보인다.
FreeRTOS는 무료이고, MCU/MPU 혹은 ESP32 기반에 사용하니 일단 좀 더 공부를 해야 할 것 같다.
1.5 FreeRTOS 관련 자료 수집
ESP의 FreeRTOS Manual
FreeRTOS Heap 관련내용
FreeRTOS 관련검색 중 우연 발견했는데, 설명이 괜찮음
1.6 ESP32의 app의 Version
OTA를 진행할 경우, application binary format안에 다음 구조체가 존재하며, image안에서 쉽게 볼수 있다.
PROJECT_VER 값
- esp_app_desc 의 version 정의
PROJECT_VER
PROJECT_VER: CONFIG_APP_PROJECT_VER
PROJECT_VER: project/version.txt
PROJECT_VER: git describe --always --tags --dirty
2. ESP32의 FreeRTOS Task의 Memory 관리
configSUPPORT_DYNAMIC_ALLOCATION
xTaskCreate ->xTaskCreatePinnedToCore
xTaskCreatePinnedToCore
xTaskCreatePinnedToCore
내부 heap (pvPortMallocTcbMem/pvPortMallocStackMem)
MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT
ESP32의 Task Heap 관리
Task Heap 확인
heap_caps_get_free_size(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)
configSUPPORT_STATIC_ALLOCATION
외부에서 설정가능
xTaskCreateStatic->xTaskCreateStaticPinnedToCore
xTaskCreateStaticPinnedToCore
Coredump (Flash)
SPIRAM Config
COMPONENT_EMBED_FILES
COMPONENT_EMBED_TXTFILES
Performance
ESP32의 내부 회로도 확인
- SPI Flash는 QPI/QSPI지만, 일반 SPI Interface 이용 (Data bus: 1bit)
- SPI PSRAM는 QPI/QSPI Interface (Data bus: 4bit)
- 둘다 같은 Bus를 이용하므로 동시사용은 불가능 CS에의 선택
SPI Flash /SPI Memory Bus는 공유 회로도 확인
문제는 같은 버스라서 동시사용이 불가능
SPI의 XIP 자료(QSPI)
SPI 의 XIP의 이용은 QSPI를 이용하여 4bit Parallel 로 통신하여 가능 (Nor의 16/8) 보다가 4bit는 나도 신기할뿐
SPI의 XIP(Execute in place)의 구성
- SPI-SRAM에서는
- SPI Flash에서는 XiP가 가능한걸로 보임 Serial로 Command/ Address/ Data 형식
Nor Flash의 경우는 Address Bus/Data bus Parallel 이며 존재하므로 XIP가 Read로 가능하지만, SPI Flash도 역시 가능하다고함
Cypress의 QSPI RAM Datasheet
구조를 보면 , Command / Address / Data 방식으로 전달하여 XiP가 가능함
ESP32의 Techincal Reference
ESP32 Hardware Degine Guide
ESP32의 Cache Policy 확인
ESP SPI의 DIO/QIO
esptool.py -p COM5 flash_id
Manufacturer: 20 // 0x20: ST ID
Device: 4016 // 0x4016 WINBOND_NEX_W25Q32_V
Detected flash size: 4MB
Hard resetting via RTS pin...
Coredump
assert(0) test 진행
3. FreeRTOS Task 정보 와 IDE 관련사항
FreeRTOS의 전체 Task 정보와 각 실시간 통계 및 점유율을 비롯하여 우선순위들을 알려고자 할 때 아래의 함수들을 이용하도록하자.
3.1 FreeRTOS의 실시간 통계 및 모니터
Linux 처럼 각 Task의 점유율과 각 상태의 통계를 알고 싶어 찾기 시작했으며, 관련함수들을 찾았는데,
간단히 시험만 해보았다.
vTaskGetRunTimeStats 함수로 FreeRTOS의 각 Task의 점유율을 쉽게 볼수 있다.
{
char dbgBuffer[ 1028*4 ];
printf("Task Abs-Time Per-Time \n");
printf("----------------------------------------------\n");
vTaskGetRunTimeStats( dbgBuffer );
printf("%s",dbgBuffer);
}
관련정보 및 설정확인
vTaskList 함수로 FreeRTOS의 각 Task의 아래 정보를 확인 ESP32의 경우 Core도 확인
{
char dbgBuffer[ 1028*4 ];
printf("Name State Prio Stack Num Core? \n");
printf("-----------------------------------------------------\n");
vTaskList( dbgBuffer );
printf("%s",dbgBuffer);
}
관련정보 및 설정확인
vTaskList 예제
3.2 ESP32의 FreeRTOS IDE 관련내용
현재 ESP에서 Ecplise 에 OpenOCD 기반 제공을 해주고 있지만, 아래와 같이 Cadence에서 별도로 제공을 해주는 것으로 보임
Ecplise 기반의 OpenOCD 연결
VS Code 기반의 OpenOCD 연결
Tensilica FreeRTOS IDE 관련내용
Cumtomized Ecplise된 Ecplise인 것 같으며 추후 각각 사용해보고 비교