单片机
返回首页

ucos-ii在MC9S12XDP512上的移植

2021-08-11 来源:eefocus

      搞了几天,总算把ucos-ii移植到MC9S12XDP512上了。做个简短的笔记。


      ucos-ii版本:2.52, 编译器:Freescale CodeWarrior5.9 芯片:MC9S12XDP512


      移植步骤:


      1.  根据向导建立新的工程,芯片选择MC9S12XDP512,其余默认配置;


      2.  将ucos-ii通用源文件复制到工程的Sources目录下下:OS_CORE.C,OS_DBG.C,OS_FLAG.C,OS_MBOX.C,OS_MEM.C,


      OS+MUTEX.C,OS_Q.C,OS_SEM.C,OS_TASK.C,OS_TIME.C,uCos_II.H,os_cfg.h并将这些文件添加到工程中;


      3. 创建新文件,并命名为includes.h,将其添加到工程中,includes.h文件内容为:

#include       /* common defines and macros */

#include 'derivative.h'      /* derivative-specific definitions */

#include           // memset函数头文件

#include   

#include   

#include   

#include    'OS_CPU.H'

#include    'os_cfg.h'

#include    'uCOS_II.H'


      4. 创建新文件OS_CPU.H,并将其添加到工程中,OS_CPU.H文件内容为:

#ifdef  OS_CPU_GLOBALS

#define OS_CPU_EXT

#else

#define OS_CPU_EXT  extern

#endif

typedef unsigned char  BOOLEAN;

typedef unsigned char  INT8U;                    /*   8 bit                    */

typedef signed   char  INT8S;                    /*   8 bit                    */

typedef unsigned int   INT16U;                   /*   16 bit                   */

typedef signed   int   INT16S;                   /*   16 bit                   */

typedef unsigned long  INT32U;                   /*   32 bit                   */

typedef signed   long  INT32S;                   /*   32 bit                   */

typedef float          FP32;                     /*                 */

typedef double         FP64;                     /*                 */

typedef unsigned char   OS_STK;                   /*                */

typedef unsigned char   OS_CPU_SR;                // CCR 8 bits

#define  OS_CRITICAL_METHOD    3

#if      OS_CRITICAL_METHOD == 1

#define  OS_ENTER_CRITICAL()  

#define  OS_EXIT_CRITICAL()  

#endif

#if      OS_CRITICAL_METHOD == 2

#define  OS_ENTER_CRITICAL()                           

#define  OS_EXIT_CRITICAL()                    

#endif

#if      OS_CRITICAL_METHOD == 3

#define  OS_ENTER_CRITICAL()  asm tpa;asm sei;asm staa cpu_sr    /* Disable interrupt */

#define  OS_EXIT_CRITICAL()   asm ldaa cpu_sr;asm tap        /* Enable interrupt                        */

#endif

#define  OS_STK_GROWTH        1              /* top to bottom            */

#define  OS_TASK_SW()         asm swi   /* software interrupt                */


      5. 创建新文件os_cpu_c.c,并添加到工程中,os_cpu_c.c文件内容较多,主要有以下部分:


      1. 以下函数均为空: OSTaskCreateHook(),OSTaskDelHook(),OSTaskSwHook(),OSTaskIdleHook(),


          OSTaskStatHook(),OSTimeTickHook(),OSInitHookBegin(),OSInitHookEnd(),OSTCBInitHook(),


      2. OSTaskStkInit()函数内容: 该函数主要模拟中断产生时CPU的压栈过程,根据芯片资料(IS12CpuV1.pdf),中断的压栈次序为:


          SP+7  RTNH:RTNL  (返回地址)

          SP+5  Y

          SP+3  X

          SP+1  D(B:A)

          SP      CCR


        由上,OSTaskStkInit()内容为:

// =============================================

// 模拟中断产生初始化堆栈

// 中断产生时,堆栈压栈过程: (参见9S12cpuV1.pdf P381)

/*

    SP+7  RTNH:RTNL  (返回地址)

    SP+5  Y

    SP+3  X

    SP+1  D(B:A)

    SP    CCR

*/

// =============================================

OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)

{

    INT16U *wstk;

    INT8U  *bstk;

 

    opt     = opt;                           // 'opt' is not used, prevent warning                     

    wstk    = (INT16U *)ptos;                // Load stack pointer                                     

    *--wstk = (INT16U)pdata;                 // Simulate call to function with argument                

    *--wstk = (INT16U)(((INT32U)task) >> 8); // Return address.  Format: PCH:PCL:PPAGE (cut out PPage) 

                                             // 函数地址构成: PCH:PCL:PPAGE

                                             

    *--wstk = (INT16U)(((INT32U)task) >> 8);                                           

    // 存储Y,X,D,CCR的当前值,实际任务还未开始,因此,X,Y,D,等也未用,可以随便取值,此处都取0

    *--wstk = (INT16U)0x0;                   // Y Register                                            

    *--wstk = (INT16U)0x0;                   // X Register                                             

    *--wstk = (INT16U)0x0;                   // D Register                                                

    bstk    = (INT8U *)wstk;                 // Convert WORD ptr to BYTE ptr to set CCR                

    *--bstk = (0xC0);                        // CCR Register (Disable STOP instruction and XIRQ)      

    *bstk = (INT8U)task;                   // Save the PPAGE register                               

                                             // 地址低8位为PPAGE 

    return ((OS_STK *)bstk);                 // Return pointer to new top-of-stack                     

}

      3. 由于CodeWarrior可以内联汇编,因此将以下4个需要由汇编编写的函数也放于Os_cpu_c.c中:OSStartHighRdy(),


          OSCtxSw(), OSIntCtxSw(),OSTickISR().注意,这4个函数都应该编写在非分页区,4个函数的内容为:

#pragma CODE_SEG  NON_BANKED

void OSStartHighRdy(void)

{

OSTaskSwHook();           //Call Hook function

asm

{

ldx OSTCBCur;          // load the value in OSTCBCur or 

                       // 偏移量0,此处实际为堆栈指针地址

lds 0,x;

inc OSRunning;           //OSRunning = 1

pula;                 // 弹出PPAGE

staa PPAGE;

nop;

rti;

}

}

void OSIntCtxSw(void)

{

OSTaskSwHook();         //Call Hook function

OSTCBCur = OSTCBHighRdy; //change OSTCBCur and OSPrioCur

OSPrioCur = OSPrioHighRdy;

asm

{

ldx OSTCBCur;         //Get the new task's TCB's address

lds 0,x;

pula;

staa PPAGE;

rti;

}   

}

void interrupt 4 OSCtxSw(void)     /*swi interrupt */

{

asm

{

  // 保存PPAGE

  ldaa PPAGE;

  psha;

  nop;

  // 在当前任务控制块中保存当前任务的堆栈指针

  ldx OSTCBCur;

  sts 0,x;

}

OSTaskSwHook(); //call Hook function

OSTCBCur = OSTCBHighRdy;

  // 得到将要重新运行任务的堆栈指针

  asm

  {

    ldx OSTCBCur;

    lds 0,x;

    

    pula;

    staa PPAGE;   // 恢复PPAGE

    nop;

    rti;      // 中断返回,恢复寄存器并运行任务

  }

}

void interrupt 7 OSTickISR(void)

{

  asm

  {

    ldaa PPAGE;

    psha;

  }         // 保存PPAGE

OSIntEnter();

if(OSIntNesting == 1)

{

  asm

  {

    ldx OSTCBCur;

    sts 0,x;

  }

}

CRGFLG |= 0x80;   // 清中断

OSTimeTick();

OSIntExit();     /* exit interrupt and task switch*/

  // 没有更高优先级的任务进入就绪态,则中断返回

  asm

  {

    pula;

    staa PPAGE;

    rti;

  }

}

#pragma CODE_SEG  DEFAULT


    6. 按自己需要修改os_cfg.h配置文件


    7. 在main.c中编写如下测试代码:

#include 'includes.h'

#define  TASK_STK_SIZE                  64       /* static size     */

OS_STK   TaskStartStkA[TASK_STK_SIZE];

OS_STK   TaskStartStkB[TASK_STK_SIZE];

void  Basic_Init(void); 

void  TaskStartA(void *data);             

void  TaskStartB(void *data);    


void main(void) {

  OSInit();

  Basic_Init();

  OSTaskCreate(TaskStartA, (void *)0, &TaskStartStkA[TASK_STK_SIZE - 1], 0);

OSTaskCreate(TaskStartB, (void *)0, &TaskStartStkB[TASK_STK_SIZE - 1], 1);    

OSStart();   

}

// 设备初始化

void Basic_Init(void)

{

  // 实时时钟配置

  RTICTL=0x49;         //10ms Interrupt

CRGINT_RTIE=1;       //Enabe Interrupt

// 端口配置

DDRB_DDRB2 = 1;     // TaskA,PB2,输出

DDRB_DDRB3 = 1;     // TaskB,PB3,输出

}

// 任务

void  TaskStartA (void *pdata)

{

pdata  = pdata;                            /* nothing  */

while (1) 

{

PORTB_PB2 =~PORTB_PB2;

OSTimeDly(100);   /* 1000ms */

}

}

void  TaskStartB (void *pdata)

{

pdata  = pdata; 

while (1) 

{

PORTB_PB3 = ~PORTB_PB3;

OSTimeDly(20);   /* 200ms */

}

}


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章