freertos V9.0.0之xTaskCreateStatic

由点到面,各个点要各个击破:

(1)

/*
 * See header file for description.
 */
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
	/* Simulate the stack frame as it would be created by a context switch
	interrupt. */
	pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
	*pxTopOfStack = portINITIAL_XPSR;	/* xPSR */
	pxTopOfStack--;
	*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK;	/* PC */
	pxTopOfStack--;
	*pxTopOfStack = ( StackType_t ) prvTaskExitError;	/* LR */


	pxTopOfStack -= 5;	/* R12, R3, R2 and R1. */
	*pxTopOfStack = ( StackType_t ) pvParameters;	/* R0 */
	pxTopOfStack -= 8;	/* R11, R10, R9, R8, R7, R6, R5 and R4. */


	return pxTopOfStack;
}



PC是啥?就是函数的地址。

嗯!!这里怎么没有SP?

那么SP是啥?就是堆栈指针,估计是Stack pointer的缩写吧。SP具体的变化情况,可以看这个文档http://blog.csdn.net/unsv29/article/details/78549303,就是临时变量等被压入栈。

那么上面这个pxPortInitialiseStack这个函数是啥?

就是在MDK仿真界面的最左面有个REgister,如下图:


至于太具体的,就有时间再说了。


( 2)

uint32_t *p1;

uint16_t *p2;

p1 = (uint32_t *) 1 + 1;

p2 = (uint32_t *) 1 + 1;

用来解释pxTopOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 );

(3)

关于数据内存地址

若:xTaskCreateStatic(vTaskLED1, "vTaskLED1", 512, NULL, 1, user1_puxStackBuffer, user1_pxTaskBuffer);

则执行完函数pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );后得到如下(为调试方便令static TCB_t *pxNewTCB;就是说加了个static):





上面介绍的是初始化newTask,就是执行prvInitialiseNewTask这个函数;

下面就是把newTask加入到readyList,就是执行prvAddNewTaskToReadyList这个函数。

这个函数里面第一句就是

	/* Ensure interrupts don't access the task lists while the lists are being
	updated. */
	taskENTER_CRITICAL();

这个函数什么作用先不管他。

好吧,把整个函数内容都贴出来吧

    taskENTER_CRITICAL();
    {
        uxCurrentNumberOfTasks++;
        if( pxCurrentTCB == NULL ) {

            pxCurrentTCB = pxNewTCB;

            if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) {
                prvInitialiseTaskLists();
            } 
        } else {

            if( xSchedulerRunning == pdFALSE ) {
								if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority ) {
										pxCurrentTCB = pxNewTCB;
								} 
            } 
        }
        uxTaskNumber++;
        traceTASK_CREATE( pxNewTCB );
        prvAddTaskToReadyList( pxNewTCB );
        portSETUP_TCB( pxNewTCB );
    }
    taskEXIT_CRITICAL();

把注释等等都填上:

static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
{
	/* Ensure interrupts don't access the task lists while the lists are being
	updated. */
	taskENTER_CRITICAL();
	{
		uxCurrentNumberOfTasks++;
		if( pxCurrentTCB == NULL )
		{
			/* There are no other tasks, or all the other tasks are in
			the suspended state - make this the current task. */
			pxCurrentTCB = pxNewTCB;

			if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 )
			{
				/* This is the first task to be created so do the preliminary
				initialisation required.  We will not recover if this call
				fails, but we will report the failure. */
				prvInitialiseTaskLists();
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}
		else
		{
			/* If the scheduler is not already running, make this task the
			current task if it is the highest priority task to be created
			so far. */
			if( xSchedulerRunning == pdFALSE )
			{
				if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority )
				{
					pxCurrentTCB = pxNewTCB;
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}

		uxTaskNumber++;

		traceTASK_CREATE( pxNewTCB );

		prvAddTaskToReadyList( pxNewTCB );

		portSETUP_TCB( pxNewTCB );
	}
	taskEXIT_CRITICAL();

	if( xSchedulerRunning != pdFALSE )
	{
		/* If the created task is of a higher priority than the current task
		then it should run now. */
		if( pxCurrentTCB->uxPriority < pxNewTCB->uxPriority )
		{
			taskYIELD_IF_USING_PREEMPTION();
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}
	}
	else
	{
		mtCOVERAGE_TEST_MARKER();
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值