初识FreeRTOS

转载于:http://www.cdus.org/cdusbk/bbs.php?id=423

今天开始学习FreeRTOS,就今天一天的学习稍做总结:
开始,对操作系统总有种恐惧的心态,不知从何下手,上午还是在看“FreeRTOS API Reference”,看了大约有二十来页,感觉也没什么,和课本上讲的操作系统差不了太多,下午开始了S800系统(基本FreeRTOS,结合利用的硬件,包括一些低层驱动的软硬件系统)。

对整个系统的架构还不是太了解,总体感觉是一个workspace有好多个project,大多的project输出为库文件,而主project去通过库文件去调用,所以,其中有很多的main函数,而且很多时候我们用"go to definition"的时候都找不到函数的定义。。。
找到mainproject的main函数:
void main(void)
{
  HWSetup();                            /* 硬件初始化 */
  bpool(mHeap,configTOTAL_HEAP_SIZE);   /* heap initialize */
  xTaskCreate( vTaskStart,              /* Create the first task */
              (signed portCHAR *)"TaskStart",
              TASK_START_STACK_SIZE,
              NULL,
              TASK_START_PRIORITY,
              NULL );
  vTaskStartScheduler();                /* Start the scheduler. */
  while(1);
}
可以看到,先进行了硬件初始化和堆的初始化,后建立一个任务,再往后就是任务调度。
再找到任务调度的函数(属于内核,在task.c中),首先又建立一个Idle Task:
xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, (
tskIDLE_PRIORITY | portPRIVILEGE_BIT ), ( xTaskHandle * ) NULL );
经过少量的初始化操作,在一个if语句中调用了 xPortStartScheduler()函数,开始任务的调度。
注意,此时中断是关闭的。而且系统中现在已存在两个任务,一个是我们建立的任务,一个是在任务调度时建立的IdleTask.每个任务对应着一个TCB(任务控制块)。
然后找到 xPortStartScheduler()函数的定义(在port.c文件中):
portBASE_TYPE xPortStartScheduler( void )
{
 /* Make PendSV and SysTick the lowest priority interrupts. */
 *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
 *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;
 /* Start the timer that generates the tick ISR.  Interrupts are disabled
 here already. */
 prvSetupTimerInterrupt();
 
 /* Initialise the critical nesting count ready for the first task. */
 uxCriticalNesting = 0;
 /* Start the first task. */
 vPortStartFirstTask();
 /* Should not get here! */
 return 0;
}
设定两个中断的优先级,然后打开时钟中断,才到了最关键的一句:vPortStartFirstTask();
此函数定义在portasm.s中,用汇编写的:
vPortStartFirstTask
 /* Use the NVIC offset register to locate the stack. */
 ldr r0, =0xE000ED08
 ldr r0, [r0]
 ldr r0, [r0]
 /* Set the msp back to the start of the stack. */
 msr msp, r0
 /* Call SVC to start the first task. */
 svc 0
最后一行:svc是一个系统调用,也就是说产生一个系统中断。那我们看看系统中断的中断服务程序是怎么写的(同样在portasm.s中):
vPortSVCHandler;
 ldr r3, =pxCurrentTCB
 ldr r1, [r3]
 ldr r0, [r1]
 ldmia r0!, {r4-r11}
 msr psp, r0
 mov r0, #0
 msr basepri, r0
 orr r14, r14, #13
 bx r14
其中用到pxCurrentTCB参数,此参数是指向当前任务TCB的指针,每个任务在建立的时候都会有一个TCB去保存任务的状态等,而TCB的第一个参数就是些任务的堆栈指针,此中断服务程序就利用了堆栈指针位置的关系进行操作,故其位置不可变。。
关于下面的一些操作暂时还没有看明白,明天接着。。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值