4.1 μC/OS II实时操作系统的移植
μC/OS II是一种开放源码的实时嵌入式操作系统,是一个可移植、可裁减、可固化的占先式多任务操作系统,已被应用到多种微处理器中,其大部分源码是用ANSI C语言编写的。移植工作包括以下几个内容:
(1)用汇编语言改写OS_CPU_A.ASM文件
该文件包括4个子程序:_OSStartHighRdy、OSCtxSw、OSIntCtxSw和OSTickISR。OSStartHighRdy()函数被OSStart()函数调用,功能是运行优先级最高的就绪任务;OSCtxSw()函数被OS Sched()函数调用,其功能是在任务级实现任务切换,任务切换用31号软中断来实现;OSIntCtxSw()函数只能在中断子程序里被OSIntExit()函数调用,由于中断的产生可能引起任务切换,因此在中断服务程序的最后会调用OSIntExit()函数调用,由于中断的产生可能引起任务切换,因此在中断服务程序的最后会调用OSIntExit()函数来检查任务就绪状态,如果满足任务切换条件(在最后一层中断里,并有高优先级任务就绪),则OSIntExit()调用此函数实现任务切换;时钟节拍函数OSTickISR()的功能如下:TMS320LF2407有4个通用定时器,其中断优先级由高到低分别为T1、T3、T2、T4,可根据实际需要选择基中的一个来实现时钟节拍。需要注意的是:调用_OSIntEnter前不能开中断。如果在调用_OSIntEnter前就开中断,有可能在OSIntNesting加1前就被中断。若发生这种情况,则当高优先级的中断调用OSIntExit()而退出时,应直接从高优先级中断里切换到任务,而不是反回到_OSTickISR(假设_OSTickISR是最后一层中断),其根本原因就在于_OSTickISR还没有来得及将OSIntNesting加1就被中断了。在用户的其他中断服务程序中也应该防止此类错误。
(2)用C语言改写OS CPU_C.C文件
本文件仅包括一个OSTaskStkInit()子程序。该函数可模仿TI公司的1$$SAVE库函数对任务堆栈进行初始化,被OSTaskCreate()函数和OSTaskCreateExt()函数所调用,该函数是用来返回任务堆栈初始化后的指针值。注意:TMS320LF2407A本身的堆栈(以下简称US)只有8级,无法作为系统堆栈使用,所以C编译器将其内部的二个突破口AR0,AR1保留,其中AR1作为堆栈指针SP,AR0用做堆栈中临时变量指针FP(在汇编程序中不要使用这二个寄存器,如果必须使用,要关中断,并注意保存和恢复)。编译器将函数和中断压进US的返回地址弹出放在SP(AR1)指南的堆栈中,并保留环境,不同的是函数只保留程序要使用的寄存器,中断要调用I$$AVE保存所有寄存器,返回时要跳转到(而不是调用)I$$REST(这两个函数可以在RTS.SRC中看到源代码)恢复寄存器,这二个函数就象8068里的中断进入和指令HRET,是移植OSTaskStkInit()函数的基础。
(3)编写OS_CPU.H文件
内容可根据μC/OS-II中的“80×86”的内容进行修改,这里仅给出关键内容:
#define OS STK GROWTH 0
#define OS ENTER CRITICAL() asm("SETC IN TM");
#define OS_EXIT CRITICAL() asm ("CLRC IN TM");
#define OS-ASKee SW() asm("INTR 31");
(4)适当OSMap Tb1[]和OSUnMapTb1[]
移植时还需要对tic /OS-II的OSMapTb1[]和O-SunMapTb1[]二个表进行适当处理,否则会出现寻址错误而使μC/OS-II无法正常运行,这是移植能否成功的重要因素之一。由于TMS320LF2407的存储器采用的是哈佛结构,Flash存储器(或外扩的ROM)位于程序区,因此,处理的方法如下:将tic /OS-II中OSMapTb1[]和OSUnMapTb1[]的数据类型从“INT8U const'改为‘INT8U’,并在链接器命令文件(.CMD)中将“.cinit”块分配到Flash存储器(或外扩的ROM中,链接选项用“-C”(ROM初始化)。这样,在程序运行时将自动对数据区的RAM进行初始化,即运行时自动将“.cinit”块中的数据复制到数据区的RAM中。
按需配置OS-FG.H,修改CPU中断向量表和外设向量表后,其他文档的内容可根据实际需要进行相应设置。至此,μC/OS-II在TMS320LF2407上的移植就完成了。
4.2 LAN91C111的编程
4.2.1 初始化
上电后,LAN91C111内部寄存器的值均设置为缺省值,CPU将根据需要设置其中的Configuration,Base和Individual Address寄存器,以保证电路正确工作。
4.2.2 发送数据包流程
(1)DSP向控制器发送ALLOCATE MEMORY命令(设置MMUCOM寄存器,通常设置为0x0020),MMU为待发送的包在控制器内部的packet buffer中分配存储空间。
(2)DSP查询Interrupt Status寄存器中的ALLOC INT位,直到该位被置成1,也可以设置Interrupt Mask中的ALLOC INT位,然后等待硬件中断,这时,MMU已经分配好存储空间。而且TX packet number放在Allocation Result寄存器中。(3)将Allocation Result寄存器中的packet number:拷贝到Packet Number:寄存器中,设置Pointer寄存器(设置为TX;WR,AUTOINC,即0x4000)。然后将包中数据从upper layer发送队列传送到控制器的Data Register。要求依次写入Status Word、Byte Count、destination address、source address、packet size、packet data、control word。
(4)DSP向控制器发送“ENQUEUE PACKET NUMBER TO TX FIFO”命令(设置MMUCOM寄存器,通常设置0x00C0),该命令将Packet Number寄存器中的packet number拷贝到TX FIFO,说明发送的包已放入队列中。同时设置Transmit control寄存器中的TXENA位。同时设置Transmit control寄存器中的TXENA位,启动transmitter。到此为止,DSP的设置工作完成,它可以IDLE,直到接收到一个控制器产生的发送中断。
(5)当控制器传送完包以后,memory中的第一个字(16bit)被CSMA/CD写入相应的Status Word,然后将TX FIFO中的packet number移到TX completion FIFO,当TX completion FIFO不为空时产生中断。
(6)DSP接收到中断后,开始执行中断处理程序,它读入Interrupt Status寄存器,如果产生发送中断,则从FIFO ports寄存器读入发送的包中的packet number,并将它写入packet number寄存器。然后从memory中读人Status Word(包括设置Pointer寄存器为TX、RD、AUTOINC,即0x6000,然后从数据寄存器中读入包的Status Word),它是EPH寄存器的镜像,再根据Status Word判断包发送是否成功。如果成功,DSP则向控制器发送RELEASE命令(设置MMUCOM寄存器,设置为0x00A0),随后控制器将释放发送包所使用的存储空间,同时设置TX INT Acknowledge寄存器,它将TX completion FIFO中的pecket unmber清除。有二种产生发送中断的方案:每发送一个包产生一个中断;每发送一个序列的包产生一个中断。通过Control寄存器的Auto Release位来选择这二种方案,而且这二种方案所使用发送中断位也有所不同。
电子发烧友App








评论