[8freeRTOS]161204_Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf
4.54MB

freeRTOS 공부를 시작하며 태스크에 대한 내용부터 필기합니다.

CMSIS (Cortex(Common) Microcontroller Software Interface Standard)

CubeIDE에서 freeRTOS를 사용할때,xtaskCreate,vtaskxx,pxreadylist~ 등 freeRTOS함수를 감싸는 ostaskCreate등의 CMSIS함수들이 있다.

FreeRTOS API에 기반한 CMSIS-RTOS를 사용하여 스레드(태스크)를 생성한다

Application: CMSIS-OS API만 사용

Wrapper: CMSIS-OS API 호출을 FreeRTOS 네이티브 호출로 변환

FreeRTOS Kernel: 실제 스레드 관리·동기화 실행

CMSIS 사용하는 이유 : 여러가지 펌웨어 버전들을 표준화하여 OS에서 API 호출방법을 편리하게 할 수 있도록 한다.
단점 : 함수 안에 freeRTOS 함수를 또 감싸며 호출하고 있어,코드 속도나 효율성면에서는 떨어진다.

Task 생성

아래에 osThreadCreate에는 여러 선택지 중 Static과 dynamic이 있는데,

크게 나누면 RAM에서 TCB의 공간과 스택 공간이 있는데, Static은 사용자가 직접 스택 메모리 배열을 선언해서 사용하고,

Dynamic은 내부의 malloc함수를 이용해 힙 메모리를 할당해 사용한다. FreeRTOS/Source/portable/MemMang/heap4.c에서 확인 가능.

osThreadCreate(CMSIS -RTOS API)
생성할 스레드(태스크)를 정의하고, xTaskCreate함수를 호출하여 생성한다.

Create의 파라미터를 →Handle이 전달한다.

cmsis_os.c의 Handle은 곧 tasks.c의 tskTaskContrlBlock 구조체포인터이다.

os_thread_def 구조체

xTaskCreate(freeRTOS)

xTaskCreate(
    vTaskFunction,        // Task 함수 포인터(함수명)
    "UART Task",          // Task 이름(디버깅 용도)
    128,                  // Task에 할당할 Stack의 깊이 (타입사이즈*바이트로 워드 단위)
    NULL,                 // Task함수로 전달할 사용자 정의 매개 변수 (void*포인터) 다양한 목적에 따라 구조체/포인터 전달.
    2,                    // Task 우선순위 (0~configMAX값-1)
    &uartTaskHandle       // 우선순위 변경, 삭제 등 API 호출 가능한 핸들, 필요 없으면 NULL

반환 값 : pdPASS (생성 성공), pdFAIL(Task생성실패)

→ 이 파라미터들로 Task를 생성한다.
);

BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,  
                        const char * const pcName,  
                        uint16_t usStackDepth,  
                        void *pvParameters,  
                        UBaseType_t uxPriority,  
                        TaskHandle_t *pxCreatedTask );
  1. TCB(Task Control Block) 메모리 힙에 동적 할당
  2. Task용 스택 메모리를 동적 할당
  3. 할당이 되면 Task를 init 및 TCB를 넘겨 ready 상태로 등록 후 pdPASS 성공상태 반환한다.
  4. pvPortMalloc함수 확인→FreeRTOS/Source/portable/MemMang/heap4.c

5. TaskControlBlock 구조체

  • 태스크 스택 포인터(SP)(어셈블리 접근성을 위해 가장 위에 위치)스택 포인터가 가리키는 ****컨텍스트에는 8개의 레지스터 세트로 구성된다.
  • xPSR,리턴 주소, LR(R14),R12, R3,R2,R1,R0 →이걸 MSP 또는 PSP에 푸시한다
  • 태스크가 마지막으로 실행되던 레지스터 값들(컨텍스트)은 태스크 스택(MSP,PSP)에 Push,pop으로 저장됨. 이걸 가리키는 스택 포인터를 TCB에 저장.
  • 태스크의 현재 상태 저장(정수값)(Ready,Blocked,Suspended)
  • 우선순위
  • 태스크 이름

TCB 구조체 코드

typedef struct tskTaskControlBlock /\* The old naming convention is used to prevent breaking kernel aware debuggers. _/  
{  ~~~~
//주요 내용만 발췌
ListItem_t            xStateListItem;    /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */
ListItem_t            xEventListItem;        /*< Used to reference a task from an event list. */
UBaseType_t            uxPriority;            /*< The priority of the task.  0 is the lowest priority. */
StackType_t            *pxStack;            /*< Points to the start of the stack. */
char                pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */

~~~~
} tskTCB;

이후 create된 태스크는 xStateListItem을 통해 순위에 따라 double linked list구조인 ready list에 저장된다.

 * Place the task represented by pxTCB into the appropriate ready list for
 * the task.  It is inserted at the end of the list.
 */
#define prvAddTaskToReadyList( pxTCB )                                                                \
    traceMOVED_TASK_TO_READY_STATE( pxTCB );                                                        \
    taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );                                                \
    vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \
    tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )
/*-----------------------------------------------------------*/

Support for Hierarchical Scheduling in FreeRTOS*

 

+ Recent posts