ucos-ii系统分析一

本文通过分析ucos-ii系统,探讨了嵌入式操作系统的原理。从操作系统的基本功能出发,详细介绍了ucos-ii的初始化过程,包括OSInit函数、任务创建、堆栈初始化和TCB数据结构等关键环节,帮助读者理解嵌入式操作系统的内部运作。
摘要由CSDN通过智能技术生成

操作系统最原始的功能在于对上层应用提供统一的硬件资源管理,这里的硬件资源包括CPU、内存、存储(文件系统)、外设(驱动管理)等等。
理解linux内核,代码庞大,功能复杂,可以通过ucos系统来窥探嵌入式操作系统工作原理。
分析ucos-ii源于,以及工程案例:
例子:

//可用keil直接仿真
//可用proteus仿真观察串口输出 ,晶振11.0592M,波特9600
#include "../ucos2/includes.h"
#include<stdio.h>
void TaskStartyya(void *yydata) reentrant;
void TaskStartyyb(void *yydata) reentrant;
void com_init(INT16U baud);
OS_STK TaskStartStkyya[MaxStkSize];//任务a堆栈空间
OS_STK TaskStartStkyyb[MaxStkSize];//任务b堆栈空间


void main(void)
{
    OSInit();    //操作系统初始化
    InitTimer0();  //定时器初始化
    com_init(9600);//串口初始化
    OSTaskCreate(TaskStartyya, (void *)0, &TaskStartStkyya[0],2);//创建第一个任务
    OSTaskCreate(TaskStartyyb, (void *)0, &TaskStartStkyyb[0],3);//创建第二个任务
    puts("There are 2 tasks");//输出提示信息
    OSStart();//多任务启动

}

void TaskStartyya(void *yydata) reentrant
{

yydata=yydata;
    printf("task1 begin\n");
    for(;;){
       OSTimeDly(OS_TICKS_PER_SEC);  //延2s
    printf("  task1 is running\n");

    }    
}

void TaskStartyyb(void *yydata) reentrant
{

yydata=yydata; 

    printf("task2 begin\n");
    for(;;){
        OSTimeDly(OS_TICKS_PER_SEC);  
printf("  TASK2 IS RUNNING\n");  
    }    
}

void com_init(INT16U baud)
{
  #define fosc 11059200
  SCON = 0x50;    //串口工作方式为1,串行允许接受   
  TMOD&=0x0f;
  TMOD|=0x20; //定时器1工作在方式2 
  if(baud<=9600) TH1=256-fosc/32/12/baud;
  else
   {PCON = 0x80;   //SMOD = 1; 波特率加倍
   TH1=256-fosc/32/12/(baud/2);
}
    TR1  = 1;            //允许定时器1工作
 // ES   = 1; //开串口中断,必须注释掉该句puts才能输出
  EA   = 1;             //开总中断
  TI=1;//要加上此句,才能用puts输出
}

这个程序的功能很简单,就是创建两个任务,两个任务每隔一段时间向屏幕输出字符串。这个程序本身也会很简单,通过分析main函数,分为操作系统初始化、相关硬件初始化、创建任务、多任务运行与调度四步。

转入ucos-ii源码,分析系统初始化,在os_core.c文件中定义了初始化函数OSInit :

void  OSInit (void)
{
#if OS_VERSION >= 204
    OSInitHookBegin();/* Call port specific initialization code*/
#endif
    OS_InitMisc(); /* Initialize miscellaneous variables */

    OS_InitRdyList(); /*Initialize the Ready List    */

    OS_InitTCBList(); /* Initialize the free list of OS_TCBs  */

    OS_InitEventList();/* Initialize the free list of OS_EVENTs */

#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
    OS_FlagInit();  /* Initialize the event flag structures  */
#endif

#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
    OS_MemInit();   /* Initialize the memory manager   */
#endif

#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
    OS_QInit();  /* Initialize the message queue structures  */
#endif

    OS_InitTaskIdle(); /* Create the Idle Task    */
#if OS_TASK_STAT_EN > 0u
    OS_InitTaskStat(); /* Create the Statistic Task                */
#endif

#if OS_TMR_EN > 0u
    OSTmr_Init();  /* Initialize the Timer Manager     */
#endif

#if OS_VERSION >= 204
    OSInitHookEnd(); /* Call port specific init. code */
#endif

#if OS_DEBUG_EN > 0u
    OSDebugInit();
#endif
}

OS_InitMisc()完成的是一些其他变量的初始化:

static  void  OS_InitMisc (void)
{
#if OS_TIME_GET_SET_EN > 0u
    OSTime        = 0uL;/* Clear the 32-bit system clock     */
#endif

    OSIntNesting = 0u;/* Clear the interrupt nesting counter  */
    OSLockNesting = 0u;/* Clear the scheduling lock counter */

    OSTaskCtr = 0u; /* Clear the number of tasks   */

    OSRunning   = OS_FALSE;/* Indicate that multitasking not started   */

    OSCtxSwCtr   = 0u;  /* Clear the context switch counter   */
    OSIdleCtr   = 0uL;   /* Clear the 32-bit idle counter  */

#if OS_TASK_STAT_EN > 0u
    OSIdleCtrRun       = 0uL;
    OSIdleCtrMax    = 0uL;
    OSStatRdy   = OS_FALSE;  /* Statistic task is not ready  */
#endif

#ifdef OS_SAFETY_CRITICAL_IEC61508
    OSSafetyCriticalStartFlag = OS_FALSE;/* Still allow creation of objects   */
#endif
}

其中包括:中断嵌套标志OSIntNesting,调度锁定标志OSLockNesting,OS标志OSRunning等。OSRunning在这里设置为FALSE,在后面OSStartHighRdy中会被设置为TRUE表示OS开始工作。

OS_InitRdyList()初始化就绪Task列表:



static  void  OS_InitRdyList (void)
{
    INT8U  i;


    OSRdyGrp      = 0u;    /* Clear the ready list   */
    for (i = 0u; i < OS_RDY_TBL_SIZE; i++) {
        OSRdyTbl[i] = 0u;
    }

    OSPrioCur     = 0u;
    OSPrioHighRdy = 0u;

    OSTCBHighRdy  = (OS_TCB *)0;
    OSTCBCur      = (OS_TCB *)0;
}

首先将OSRdyTbl[]数组中全部初始化0,同时将OSPrioCur/OSTCBCur

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值