今天開始有決心來學習freertos 的源碼,因爲我感覺非開始不行了。(本文章沒有完成,完成後會去掉。)
我從freertos 官網下載了源代碼(10.1.1)。下載源代碼很簡單,只需要在搜索網站上輸入“freertos” 在下面就出現主頁面。點擊進去下載就好了。這個就不多說了,這是我的第一篇學習freertos 的文章,所以提了一下上面的話。謝謝大家提出寶貴意見。
今天的主角:xTaskCreate()
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask
)
當我看到這個函數的時候,我第一個想法就是: 它的參數是什麼意思?有什麼作用?
所以我下面的就逐一去找這些參數的定義。
(1)TaskFunction_t : typedef void (*TaskFunction_t)( void * ); 很顯然是函數指針
(2)const char * const pcName : 任務名字
(3)configSTACK_DEPTH_TYPE : #define configSTACK_DEPTH_TYPE uint16_t 是無符號的2字節數值
(4)void * const pvParameters :從名字看是要傳入的參數
(5)UBaseType_t uxPriority : typedef unsigned short UBaseType_t; 是一個無符號的整形數
(6)TaskHandle_t * const pxCreatedTask :這裏面有一個結構體指針。下面列出來
typedef struct tskTaskControlBlock
{
volatile StackType_t *pxTopOfStack;
#if ( portUSING_MPU_WRAPPERS == 1 )
xMPU_SETTINGS xMPUSettings;
#endif
ListItem_t xStateListItem;
ListItem_t xEventListItem;
UBaseType_t uxPriority;
StackType_t *pxStack; /*< Points to the start of the stack. */
char pcTaskName[ configMAX_TASK_NAME_LEN ];
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
StackType_t *pxEndOfStack;
#endif
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
UBaseType_t uxCriticalNesting;
#endif
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTCBNumber;
UBaseType_t uxTaskNumber;
#endif
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxBasePriority;
UBaseType_t uxMutexesHeld;
#endif
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
TaskHookFunction_t pxTaskTag;
#endif
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )
void *pvThreadLocalStoragePointers[configNUM_THREAD_LOCAL_STORAGE_POINTERS ];
#endif
#if( configGENERATE_RUN_TIME_STATS == 1 )
uint32_t ulRunTimeCounter;
#endif
#if ( configUSE_NEWLIB_REENTRANT == 1 )
struct _reent xNewLib_reent;
#endif
#if( configUSE_TASK_NOTIFICATIONS == 1 )
volatile uint32_t ulNotifiedValue;
volatile uint8_t ucNotifyState;
#endif
#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
uint8_t ucStaticallyAllocated;
#endif
#if( INCLUDE_xTaskAbortDelay == 1 )
uint8_t ucDelayAborted;
#endif
#if( configUSE_POSIX_ERRNO == 1 )
int iTaskErrno;
#endif
} tskTCB;
上面的代碼,我刪除了很多的註釋。不刪除註釋的話,顯示的會很亂。看到這個結構體這麼大,我感覺肯定很重要。認真去看他的每一個成員。
(1)volatile StackType_t *pxTopOfStack; :pxTopOfStack 從名字看,是指向棧的最頂端。
這個裏面還用了一個很重要的關鍵字:volatile
(2)xMPU_SETTINGS xMPUSettings; xMPU_SETTINGS 是一個結構體,
typedef struct MPU_SETTINGS
{
xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ];
} xMPU_SETTINGS;
typedef struct MPU_REGION_REGISTERS
{
uint32_t ulRegionBaseAddress;
uint32_t ulRegionAttribute;
} xMPU_REGION_REGISTERS;
從代碼看到xRegion 是一個帶有區域基地址和區域屬性的數組結構體。那麼我又想到了一個問題,這個區域是做什麼的啊?