一.
划重点,划重点,划重点.
线程就是freertos运行管理的最小单位.一个线程有自己的生命周期,可以是一段时间也可以是forever.
具体看开发人员对于线程的规划,几个线程,每个线程处理什么事情.
先来看看线程长啥样?(任务是线程的别名,为了方便以后都称任务)
typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */
{
volatile StackType_t *pxTopOfStack; /*< 任务的桟顶. */
ListItem_t xStateListItem; /*< 任务的状态列表项,表明当前任务所处的状态 */
ListItem_t xEventListItem; /*< 任务的事件列表项,表明当前任务所持有的事件状态 */
UBaseType_t uxPriority; /*< 任务的优先级. */
StackType_t *pxStack; /*< 任务的堆栈. */
char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< 任务的名字. */
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
StackType_t *pxEndOfStack; /*< 如果堆栈是先上增长,需要记录堆栈桟底. */
#endif
#if ( configUSE_MUTEXES == 1 )
UBaseType_t uxBasePriority; /*< 如果使用锁,记录任务优先级,当优先级反转复原后,恢复之前的优先级. */
UBaseType_t uxMutexesHeld;
#endif
#if( configUSE_TASK_NOTIFICATIONS == 1 )
volatile uint32_t ulNotifiedValue; /*< 任务的通知数值和状态. */
volatile uint8_t ucNotifyState;
#endif
} tskTCB;
typedef tskTCB TCB_t;
哇塞,内容有点多.不要慌,先...自行脑补
二.任务的创建.
任务可以静态或者动态创建,静态和动态是内存管理的事情,后面默认都是动态创建.对于主线的理解没有任何影响.
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
{
TCB_t *pxNewTCB;
BaseType_t xReturn;
/*判断堆栈的增长方向,一般都是向下增长*/
#if( portSTACK_GROWTH > 0 )
{
pxNewTCB = ( TCB_t * ) pvPortMalloc( size