6979|0

2056

帖子

0

TA的资源

五彩晶圆(初级)

楼主
 

TI Sitara AM335x系统之转载别人的关于uCosII在AM1808上的移植 [复制链接]



这篇文章转载来自德州仪器在线社区写的很好希望对大家有用
uCosIIAM1808上的移植
准备用AM1808做一个轻量级的应用,就想到了uCOS-II操作系统,之前使用过该操作系统都是利用别人移植好的工程,顶多就是做一些简单的修改,这次觉得uCOS-II自己也用过很多了,还没有移植过一回,正好趁此机会深入了解一下。网上找了一个uCOS-IIATMELARM9上移植的版本,版本号是V2.88。决定就从它开始了。后面称之为uC-SAM9263
使用的硬件开发板是国产的hawk板子,使用串口连接,用sfh_omap-l138.exe烧写程序到NAND Flash中。开发环境使用CCS5。使用StarterWare提供的bootloader程序引导系统,在bootloader中,已经配置好了系统参数,所以ucosII就不用再对系统进行初始化。
第一步:建立工程,File->New->CCS Project,输入工程名,选择器件,再选择一个空的工程。如下图所示:
完成后产生一个空的工程在工程浏览栏,如下图所示:
第二步:根据StarterWare中提供的例子,修改AM1808.cmd文件:如下所示:
-stack  0x8000                             /* SOFTWARE STACK SIZE           */
-heap   0x4000                             /* HEAP AREA SIZE                */
-e Entry
MEMORY
{
    EMIFACS0:  o = 0x40000000  l = 0x20000000 /* 512MB SDRAM Data (CS0)*/
    EMIFACS2:  o = 0x60000000  l = 0x02000000 /* 32MB Async Data (CS2) */
    EMIFACS3:  o = 0x62000000  l = 0x02000000 /* 32MB Async Data (CS3) */
    EMIFACS4:  o = 0x64000000  l = 0x02000000 /* 32MB Async Data (CS4) */
    EMIFACS5:  o = 0x66000000  l = 0x02000000 /* 32MB Async Data (CS5) */
    SHRAM:     o = 0x80000000  l = 0x00020000 /* 128kB Shared RAM */
    DDR_MEM     : org = 0xC1080000   len = 0x2F7FFFF     /* RAM */
    ARMROM:    o = 0xFFFD0000  l = 0x00010000 /* 64kB ARM local ROM */
    ARMRAM:    o = 0xFFFF0000  l = 0x00002000 /* 8kB ARM local RAM */
}
SECTIONS
{
    .init   : {
      system_config.lib (.text)
        } load > 0xC1080000
    .text    : load > DDR_MEM              /* CODE               */
.data    : load > DDR_MEM
    .bss     : load > DDR_MEM              /* GLOBAL & STATIC VARS  */
     RUN_START(bss_start),
RUN_END(bss_end)
.binit         >  DDR_MEM
    .init_array    >  DDR_MEM
    .args          >  DDR_MEM
    .neardata      >  DDR_MEM
    .fardata       >  DDR_MEM
    .rodata        >  DDR_MEM
    .const   : load > DDR_MEM              /* SOFTWARE SYSTEM STACK        */
    .cinit   : load > DDR_MEM              /* SOFTWARE SYSTEM STACK        */
    .stack   : load > 0xC3FF7FFC           /* SOFTWARE SYSTEM STACK     */
}
第三步:建立工程目录
在生产CCS工程时,就建立了一个文件夹,uSys/Project。删除刚才建立的main.c文件。在此文件夹下建立SoftWare目录,目录下建立AppBSPHWLibOSUser文件夹和下级目录。如下图所示:
其中,App是应用程序目录,BSP是板级支持包,主要是配置开发板启动初始化等工作。OS里面有几个文件夹,放操作系统源文件,系统配置文件等。还有一个HWLib,这个目录放置AM1808的硬件库,这是TI提供的StarterWare软件包的一部分,包括工程中用到的启动代码,驱动代码或库文件。
User暂时没有用,准备用来放用户的应用文件。
App目录中建立App.cApp.h文件,从uC-SAM9263拷贝其它文件到该目录。
BSP目录中建立两个空文件如图所示。
HWLib目录:
拷贝StarterWare中的system_config.lib  utils.lib两个库和driversplatforminlcude目录如图所示。当然,也可以不用StarterWare包中的库文件,可以直接复制其中的源文件到工程目录下面,在这上面修改即可,以保证工程的独立性并且不影响StarterWare包源代码。其中drivers目录就是复制源文件。注意,并不是所有文件都要加入工程中,可以参考相应的StarterWare工程,从中提取有用的文件加入工程。
uC-SAM9263工程中拷贝操作系统源代码到工作目录,结构如下所示:
第四步:建立应用程序。
App.c中,建立main函数,并建立一个任务,也可以从其它地方复制过来。
BSP.C中,做开发板的初始化。由于bootloader已经对硬件做好了配置,这里要做的是在OS启动前,关闭所有中断,OSStart()运行以后,在用户任务中初始化硬件,配置中断,配置一个系统tick时钟。
uCOS-II操作系统需要一个时钟作为系统tick。配置Timer2作为一个64bit的定时器,产生系统tick。注意,Timer2使用的系统时钟是在soc_AM1808.h文件中定义的。
然后配置中断,把用户中断服务程序的函数指针注册到系统的中断向量表。这里调用的函数都是在system_config.lib库中定义的。
在中断服务程序中调用OSTimeTick()函数,这是一个系统服务函数。进行系统定时操作。
第五步:系统移植。
系统移植就是要让uCOS-II操作系统运行与目标CPU上,一般只需改os_cpu.hos_cpu_c.cos_cpu_a.asm三个文件,这3个文件和CPU相关。在移植之前,先配置os_cfg.h文件,其实,在系统正常工作之前,可以注销所有不需要的功能,这里先注释掉#define OS_APP_HOOKS_EN           0
一个一个来,首先是OS_CPU_C.C文件,该文件主要是定义一些HOOK函数,这些函数在任务调度前或者创建前被调用,让用户有一个做点什么事的机会。这些函数都有一个宏定义开关来打开或者注销。如果有编译不通过的注销就可以了。还有一个配置任务堆栈的函数OSTaskStkInit()该函数在任务运行前初始化堆栈,并设置系统模式,可以看到,操作系统运行于SVC模式。
修改os_cpu_a.asm文件,该文件中使用到的函数有  
OS_CPU_SR  OS_CPU_SR_Save(void);
void       OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
void       OSCtxSw(void);
void       OSIntCtxSw(void);
void       OSStartHighRdy(void);
void       OS_CPU_ARM_ExceptIrqHndlr(void);
该文件由uC-SAM9263工程复制过来,由于原先的开发环境是IAR,而现在改为CCS5IAR使用的是符合ARM汇编标准的编译器,而CCS5使用GNU编译器,两个编译器的汇编伪代码定义不一样。首先要处理伪代码符合GNU汇编标准。这一部分参考GNU标准和系统提供的例程。
OS_CPU_SR_Save和 OS_CPU_SR_Restore函数提供系统进入临界代码的保护,当os_cpu.h文件中OS_CRITICAL_METHOD定义为3时,使用这两个文件保存CPSR寄存器到一个临时变量。
#if OS_CRITICAL_METHOD == 3     /* See OS_CPU_A.ASM */
  OS_CPU_SR  OS_CPU_SR_Save(void);
  void        OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
#endif
这两个文件不需要修改
OSStartHighRdy函数功能是跳转到最高优先级任务,该函数在启动时只运行一次,首先调用一个hook函数,然后修改OSRunning变量为1,标识系统进入运行状态,再切换到最高优先级任务,最高优先级任务堆栈已经在OS_CPU_C.C文件中的OSTaskStkInit()函数定义,任务堆栈指针是任务控制块OS_TCB的第一个变量:OS_STK *OSTCBStkPtr;
该堆栈组织形式如下:
高地址 PC
LR
R12
R11
.
.
R0
低地址 CPSR
首先要明白一个概念,一般的ARM编译器使用的堆栈是满递减堆栈,即堆栈的基指针在高地址,向低地址生长,栈顶指针指向最后一个压栈地址。通过STMFD和LDMFD指令压栈和出栈时,如:LDMFD   SP!, {R0-R12, LR, PC}^ ,寄存器列表可包含16个可见寄存器(R0~R15)的任意集合或全部,列表中寄存器的次序是不重要的,不影响存取的次序和指令执行后寄存器中的值,有一个约定,总是把编号低的寄存器对应于存储器的低地址。也就是说,编号最低的寄存器保存到堆栈的最低地址或从最低地址取出。
在这个出栈指令中,最后的^号,表示出栈时同时要用SPSR恢复CPSR
OSStartHighRdy跳转到用户任务,用户任务是一个死循环,永远不会再返回到这里了。这也就是当用户任务有返回时,系统会死机的原因。
OSCtxSw函数负责任务切换,首先保存当前任务堆栈,然后把任务堆栈指针赋值给任务控制块第一个变量OSTCBStkPtr。 调用一个HOOK函数,最后取出最高优先级任务控制块的第一个变量,即任务堆栈指针,把它赋值给SP,用这个SP恢复最高优先级任务。
OSIntCtxSw函数是中断中的任务切换,由OSIntExit函数调用,而_OSIntExit函数在中断退出到任务时被调用。
OSIntCtxSw函数和OSCtxSw的基本功能是相同的,都是任务切换,但是前者不保存任务堆栈,因为该堆栈在中断处理时已经被保存过了,它只需要做后面的任务切换工作即可。
OS_CPU_ARM_ExceptIrqHndlr函数处理:
该函数是系统IRQ中断的唯一入口函数,当ARM系统发生IRQ中断时,PC指针就会跳转到该函数,在这里处理中断。
我们知道,AM1808CPU处理中断是通过内存中的中断向量表进行散转的,系统直接把中断服务程序函数指针送到HIPVR2寄存器,执行效率比较高。但是操作系统的中断服务程序需要统一处理,比如任务堆栈的入栈出栈,中断嵌套,中断退出的任务切换等。所以要在system_config工程中修改ARM中断向量表,在startup.c文件中修改如下:
static unsigned int const vecTbl[14]=
{
    0xE59FF018,
    0xE59FF018,
    0xE59FF018,
    0xE59FF018,
    0xE59FF014,
    0xE24FF008,
    0xE59FF010,
    0xE59FF010,
    (unsigned int)Entry,
    (unsigned int)UndefInstHandler,
    (unsigned int)SWIHandler,
    (unsigned int)AbortHandler,
    //(unsigned int)IRQHandler,
    (unsigned int)OS_CPU_ARM_ExceptIrqHndlr,
    (unsigned int)FIQHandler
};
然后重新编译,把编译好的lib文件复制到工程中HWLib目录。
中断服务程序 OS_CPU_ARM_ExceptIrqHndlr 首先切换到SVC模式下,保存任务堆栈,然后根据OSIntNesting的值,判断是否中断嵌套,如果没有嵌套,表示该中断是打断了一个任务,就执行OS_CPU_ARM_IRQHndlr_BreakTask函数,反之执行OS_CPU_ARM_IRQHndlr_BreakIRQ函数。
OS_CPU_ARM_IRQHndlr_BreakTask函数:
首先保存当前堆栈指针到当前任务控制块的第一个变量,然后把异常堆栈指针给SP.再通过HIPVR2调用中断服务程序,返回后恢复各个模式的堆栈,调用OSIntExit函数,检查是否切换任务,退出中断。
OS_CPU_ARM_IRQHndlr_BreakIRQ函数:
处理中断嵌套情况,首先把当前SP存储到异常堆栈中,然后通过HIPVR2调用中断服务程序。返回后直接对OSIntNESTING减一,并不调用OSIntExit函数。退出中断。
IRQ中断服务程序要修改的是ARMGNU格式的转换,在中断跳转时读取HIPVR2寄存器的值,然后据此跳转。其它地方不用修改。
第六步:编译,除错。其中的错误大多数都是找不到定义,Project->Properties中,Build->ARM Compiler->Include Options。在页面中添加include路径:"../SoftWare/HWLib/include/armv5/am1808"
"../SoftWare/HWLib/include/armv5"
"../SoftWare/HWLib/include"
"../SoftWare/HWLib/include/hw"
"../SoftWare/HWLib"
"../SoftWare/OS/Ports/ARM"
"../SoftWare/OS/Source"
"../SoftWare/OS/uC-CPU/ARM"
"../SoftWare/OS/uC-CPU"
"../SoftWare/App"
"../SoftWare/BSP"
"../SoftWare/User"
ARM Linker->File SearchPath页面中,在包含库文件一栏中添加库文件
"utils.lib"
"system_config.lib"
在搜索路径一栏中,添加路径
"../SoftWare/OS/uC-CPU/ARM"
"../SoftWare/HWLib/include"
"../SoftWare/HWLib"
注意的是,DebugRelease选项都必须配置一次。
移植成功!
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表