打印

UCOSII讨论:关于移植部分

[复制链接]
4836|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Swd21ic|  楼主 | 2008-2-2 21:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
找了下好象没有专门的论坛讲ucosii的..

不知道哪个论坛讨论这个比较多.请各位推荐下

最近在搞ucosii的移植,主要是在micrium官方例程的做一些小的改动.或者说是完全弄明白例程.

处理器:  AT91SAM7Sxx
IDE:    IAR
UCOS版本:2.8x

前段时间看了了好一阵把绝大部分弄懂了.期间包扩IAR编译器,ARM汇编,ATPCS规则等.. 但还是积累了一些问题,没人提点始终搞不清.大部分是关于IRQ中断的.

所以想找个地方交流下.. 不知道21ic行不行,系统区那边实在太冷了.
估计在年后可以出一篇针对ARM移植的要点心得..也给自己总结总结.: )


相关帖子

沙发
machunshui| | 2008-2-2 23:45 | 只看该作者

前一阵子,看了zlg针对lpc的移植

前一阵子,看了zlg针对lpc的移植(基于ads的)
顺便也看了一下IAR下针对lpc系列的移植.

zlg采用了软件中断的方法进行非中断任务切换,这样中断任务切换和非中断任务切换可以共用一个任务切换子函数,用户程序工作在用户模式.

IAR下的针对LPC的移植,中断任务切换和非中断任务切换的切换子函数是不相同的,用户程序工作在管理模式,
IAR采用的中断初始化的方法很特别,就是在BSP里,先把中断区域重定位到RAM区,直接写汇编语句的二进制码到相应的中断入口处,用于跳转公共的中断处理函数,在该函数里,查询具体的用户中断处理程序的入口地址,并跳转到具体的用户中断处理程序.

其实,研究别人对ucos的移植,是一种很好的深入学习ARM的方法.

要搞清楚,需要三个方面的知识:

1.arm的编程体系结构,几种模式的应用,特别注意当前的SP,LR,是那种模式的.
一定搞清楚数据出入栈的位置关系.
2.arm的汇编语言.
3.arm的启动文件,中断是如何处理的.

可惜,楼主的是Atmel的arm,要是lpc的arm,我倒是基本明白.
两者的中断控制器的细节,应该还是有些差别的,
不知道会不会是类似的.

另外,我认为,看别人的移植主要是用来学习比较好,最好别自己移植.

使用特权

评论回复
板凳
Swd21ic|  楼主 | 2008-2-3 09:58 | 只看该作者

Re

楼上说的对.

我也是先看别人的移植例程.. 不过几个移植版本在中断处理那块略有差异.
所以想完全理解透彻之后做出改进.
或者哪一个版本是最好.就沿用那个版本的移植.

如果是针对IAR的移植,由于是ucos官方给的.LPC和AT应该是几乎完全相同的.
只是在中断处理那一个对是VIC一个是对AIC进行操作..但ADS里我就没看过了.
ADS针对LPC的移植应该都是zlg搞的.我只知道用了软中断..但不理解.

IAR下的任务切换.直接是用
BL OSCtxSw.把PC保存到了SVC的LR中.其他的用普通压栈的方式了.

另外你说的3点我应该说是基本熟悉了.第3点我能看普通启动文件的IRQ处理,
但ucosii的有几个小细节有糊涂的地方.

我觉得你的理解蛮细致的...呵呵.
有机会讨论讨论. : )

使用特权

评论回复
地板
machunshui| | 2008-2-3 10:27 | 只看该作者

觉得IAR的移植比较好

觉得IAR的移植比较好。

zlg的移植软件中断的方法,模式转换特别繁杂,但是看看确实能加强对ARM的理解.

使用特权

评论回复
5
Swd21ic|  楼主 | 2008-2-3 12:23 | 只看该作者

Re..~

..
但为什么IAR移植. 中断服务程根本不可以重入..就用户c处理那一段是在irq模式下且I位被屏蔽了.

但是原来Atmel的普通启动文件对于irq的处理是 先进去压3个字节r0, lr_irq, spsr_irq到irq堆栈..然后切换到svc去处理用户的服务程序.(i位没屏蔽).处理完后再切回irq出栈. .整个过程比较合理.。

不过如果ucos也使用这种方法的话.那么每个任务的堆栈都必须扩展出一段留给isr..因为在svc下,每个任务的堆栈都不同..而统一在irq下处理是可以.但为什么中断不可重入了.。晕了晕了..
X_X

使用特权

评论回复
6
machunshui| | 2008-2-3 20:29 | 只看该作者

楼主看的中断处理是这样的吗?

楼主看的中断处理是这样的吗?

使用特权

评论回复
7
Swd21ic|  楼主 | 2008-2-3 21:20 | 只看该作者

Re

这是第一个版本.我有这个版本,它是和ucos那个官方ppt AN1014对应的.

但现在你去ucos官方下的话有点不同... 但思路好象是差不多的.

这个版本你都理解了么..?

使用特权

评论回复
8
machunshui| | 2008-2-3 23:40 | 只看该作者

没试过中断嵌套

没试过中断嵌套.

不过感觉,用户中断处理程序自己转换到svc模式,开中断,处理自己的程序,应该能实现中断嵌套啊.当然嵌套多了,任务的堆栈要求是比较大的.

没有试过中断嵌套,lz试过是不行的吗?

使用特权

评论回复
9
machunshui| | 2008-2-4 00:00 | 只看该作者

网上找了一个号称能稳定运行的支持中断嵌套的对44b0x的移植

;/****************************************Copyright (c)**************************************************
;**                                       中南民族大学
;**                                     电子信息工程学院
;**                                    2005级电子信息工程  
;**                                    yangbin6b210@yahoo.com.cn
;**                                 
;**
;**----------------------------------------文件信息------------------------------------------------------
;**文   件   名: os_cpu_s.s
;**创   建   人: 杨斌
;**最后修改日期: 2007年12月12日
;**描        述: μCOS-II在S3C44B0X上的移植代码汇编代码部分,用ADS1.2编译
;**
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
NoInt        EQU    0x80

SVC32Mode    EQU    0x13
IRQ32Mode    EQU    0x12
FIQ32Mode    EQU    0x11
SYS32Mode    EQU    0X1F





        CODE32

        AREA    |subr|, CODE, READONLY
        
        IMPORT    OSIntNesting
        IMPORT  OSTCBCur
        IMPORT    IsrIRQ
        IMPORT    OSIntExit
        IMPORT    OSTaskSwHook
        IMPORT  OSTCBCur
        IMPORT  OSTCBHighRdy
        IMPORT  OSPrioCur                   
        IMPORT  OSPrioHighRdy 
        IMPORT    IRQStack
        IMPORT    OSRunning
        
        EXPORT    OSIRQISR
        EXPORT    OSIntCtxSw
        EXPORT    OS_TASK_SW
        EXPORT    OSStartHighRdy
        EXPORT    OS_ENTER_CRITICAL
        EXPORT    OS_EXIT_CRITICAL



;/*********************************************************************************************************
;** 函数名称: OSIRQISR
;** 功能描述: 中断进入和退出时的接口
;** 输 入:   无
;**          
;**          
;** 输 出 :  无  
;** 全局变量: OSIntNesting、OSTCBCur、IRQStack 
;** 调用模块: 无
;** 
;** 作 者: 杨斌
;** 日 期: 2007年12月12日
;**-------------------------------------------------------------------------------------------------------
;  系统模式堆栈            IRQ模式堆栈
;    |PC  |                    |LR  |=断点处的将要执行的PC值                        
;    |LR  |                     |R3  |        
;    |R12 |                    |R2  |
;    |R11 |                    |R1  |
;    |R10 |                    |R0  |
;    |R9  |                    |LR  |=系统模式的LR
;    |R8  |                    |SP  |=系统模式的SP
;    |R7  |                SP→|SPSR|=断点处的CPSR
;    |R6  |
;    |R5  |
;    |R4  |
;    |R3  |
;    |R2  |
;    |R1  |
;    |R0  |    
;     |CPSR|←SP
;/********************************************************************************************************/
OSIRQISR
        SUB        LR,LR,#4                            ;调整返回地址
        STMFD    SP!,{R0-R3,LR}
        MRS        R3,SPSR
        STMFD    SP,{R3,SP,LR}^                        ;                            系统模式SP→|R0  |                        
        
        SUB        SP,SP,#4*3                            ;                            系统模式SP→|SPSR|
        
        LDR        R0,=OSIntNesting
        LDRB    R1,[R0]
        ADD        R1,R1,#1
        STRB    R1,[R0]                                ;OSIntNesting加1                                                        
        
        MOV        R2,LR
        MSR     CPSR_c, #(NoInt | SYS32Mode)
        CMP        R1,#1
        BNE        OSIRQ_NEXT                            ;若OSIntNesting为1,则保存当前任务的寄存器到当前任务的堆栈中
        STMFD    SP!,{R2}                            ;保存当前任务的PC,            系统模式SP→|PC  |
        STMFD    SP!,{LR}                            ;保存当前任务的LR,             系统模式SP→|LR  |
        STMFD    SP!,{R4-R12}                        ;保存当前任务的R4-R12,        系统模式SP→|R4  |
        STR        R3,[SP,#-5*4]                        ;保存当前任务的CPSR        
        
        MSR     CPSR_c, #(NoInt | IRQ32Mode)        ;进入IRQ模式
        ADD        SP,SP,#4*3                            ;                            IRQ模式SP→ |R0  |
        LDMFD    SP,{R0-R3}                            ;取出R0-R3
        SUB        SP,SP,#4*3                            ;                            IRQ模式SP→ |SPSR|
        MSR     CPSR_c, #(NoInt | SYS32Mode)        ;进入系统模式
        STMFD    SP!,{R0-R3}                            ;保存R0-R3,                系统模式SP→|R0  |    
        SUB        SP,SP,#4                            ;调整SP,                    系统模式SP→|CPSR|
        
        LDR        R0,=OSTCBCur
        LDR        R0,[R0]
        STR        SP,[R0]                                ;OSTCBCur->OSTCBStkPtr=SP
        
OSIRQ_NEXT        
        BL        IsrIRQ                                ;调用IRQ中断服务函数,在此中断服务函数中必须清除中断挂起位
        
        BL      OSIntExit                            ;调用推出系统中断函数,在此函数中OSIntNesting减1,也有可能会切换到其他任务中
        
        MSR     CPSR_c, #(NoInt | IRQ32Mode)        ;进入IRQ模式。
        
        LDR        R0,=OSIntNesting                    
        LDRB    R0,[R0]
        CMP        R0,#0                                ;若OSIntNesting=0则表明这是第一层中断
        BEQ        OSIRQ_LEAVE
        
        LDMFD    SP,{R0,SP,LR}^                        ;程序运行到此处,此时处在嵌套中断中
        MSR        SPSR_cxsf,R0                        ;恢复系统模式的SP,LR,IRQ模式SPSR
        ADD        SP,SP,#4*3                            ;调整IRQ模式SP,            IRQ模式SP→ |R0  |
        LDMFD    SP!,{R0-R3,PC}^                        ;恢复R0-R3,PC,CPSR,        IRQ模式SP→ |X     |←上一层中断的堆栈顶部
        
OSIRQ_LEAVE                                                                            
        LDR        R0,=IRQStack                        ;程序运行到此处,表明这是第一层中断且不需要切换任务    
        LDR        R0,[R0]
        MOV        SP,R0                                ;                            IRQ模式SP→ |X   |←中断模式堆栈栈底
        SUB        SP,SP,#8*4                            ;                            IRQ模式SP→ |SPSR|
        
        LDMFD    SP,{R0,SP,LR}^                        ;恢复系统模式的SP,LR,        系统模式SP→|X   |←当前任务中断时的SP
        MSR        SPSR_cxsf,R0                        ;恢复IRQ模式SPSR
        ADD        SP,SP,#4*3                            ;调整IRQ模式SP,            IRQ模式SP→ |R0  |            
        
        MSR     CPSR_c, #(NoInt | SYS32Mode)        ;切换到系统模式,            
        SUB        SP,SP,#11*4                            ;调整系统模式SP,            系统模式SP→|R4  |
        LDMFD    SP,{R4-R12}                            ;恢复R4-R12
        ADD        SP,SP,#11*4                            ;调整系统模式SP,            系统模式SP→|X   |←当前任务中断时的SP
        
        MSR     CPSR_c, #(NoInt | IRQ32Mode)        ;切换到IRQ模式
        LDMFD    SP!,{R0-R3,PC}^                        ;恢复R0-R3、CPSR并从中断返回到当前任务断点处
        
;/*********************************************************************************************************
;** 函数名称: OSIntCtxSw
;** 功能描述: 中断级任务切换
;** 输 入:   IRQ模式堆栈结构(出栈次序):SPSR、SP(系统模式)、LR(系统模式)、R0-R3、LR 
;**              当前任务(系统模式)堆栈结构:CPSR、R0-R12、LR、PC          
;**          
;** 输 出 :  无  
;** 全局变量: OSTCBHighRdy、OSTCBCur、OSPrioCur、OSPrioHighRdy、IRQStack
;** 调用模块: OSTaskSwHook
;** 
;** 作 者: 杨斌
;** 日 期: 2007年12月13日
;**-------------------------------------------------------------------------------------------------------
;/********************************************************************************************************/
OSIntCtxSw
        BL        OSTaskSwHook                            ;调用钩子函数OSTaskSwHook()
        
           MSR     CPSR_c, #(NoInt | IRQ32Mode)
           LDR     R0, =OSTCBHighRdy
        LDR     R0, [R0]
        LDR     R1, =OSTCBCur
        STR        R0,    [R1]                                ;OSTCBCur=OSTCBHighRdy
        
        LDR        R0,=OSPrioCur
        LDR        R1,=OSPrioHighRdy
        LDRB    R1,[R1]
        STRB    R1,[R0]                                    ;OSPrioCur=OSPrioHighRdy
       
        LDR        R0,=IRQStack
        LDR        R0,[R0]
        SUB        R0,R0,#4                                ;
        MOV        SP,R0                                    ;IRQ模式堆栈保留一个字
        
        MSR     CPSR_c, #(NoInt | SYS32Mode)            ;进入系统模式
        LDR     R2, =OSTCBHighRdy
        LDR     R2, [R2]                                
        LDR        R2, [R2]                                ;取得新任务堆栈指针OSTCBHighRdy->OSTCBStkPtr并存入R2中
       
        LDR        R1,[R2]                                    ;取得新任务的CPSR存入R1中
        LDR        R3,[R2,#15*4]                            ;取得新任务的PC存入R3中
        STR        R3,[R0]                                    ;把新任务的PC存入IRQ模式的堆栈中
        
        MSR     CPSR_c, #(NoInt | IRQ32Mode)            ;进入IRQ模式
        MSR        SPSR_cxsf,R1                            ;把新任务的CPSR保存到IRQ模式的SPSR中
        
        MSR     CPSR_c, #(NoInt | SYS32Mode)            ;进入系统模式                       
          ADD        R2,R2,#4                                ;调整新任务堆栈指针
          MOV        SP,R2                                    ;                            系统模式SP→|R0  |
          LDMFD    SP!,{R0-R12,LR}                            ;恢复新任务的R0-R12,LR,    系统模式SP→|PC  |    
          ADD        SP,SP,#4                                ;调整系统模式堆栈指针
          
          MSR     CPSR_c, #(NoInt | IRQ32Mode)            ;进入IRQ模式
          LDMFD    SP!,{PC}^                                ;恢复新任务的CPSR、PC和IRQ模式SP


好像也没什么特别的,就是转换到系统模式,运行用户中断处理程序,运行完毕切换会中断模式.

使用特权

评论回复
10
Swd21ic|  楼主 | 2008-2-4 10:16 | 只看该作者

Re

实际应用中必须支持中断嵌套..

不然性能比前后台都差.除了tick中断以外.一般系统都会有其他中断的.
比如串口接受..之类.

不懂为什么官方的居然会不支持中断嵌套?..

你上面那个例子是跑在SYS下..好象以前也有官方例程跑在SYS,现在大多是SVC模式了...有什么实质性的区别.除了对spsr_svc换成对cpsr....

使用特权

评论回复
11
Swd21ic|  楼主 | 2008-2-16 11:29 | 只看该作者

machunshui..来看看..公司没人能讨论..T_T

最近在看移植方面的内容..主要参考的是官方的移植范例.. 但手上还有其他几个范例.发现有几个地方还是不明白的,希望高人能解答.大家也一起讨论讨论..

1.复位后默认是管理模式SVC,在前后台跑程序时Atmel给的例程也是SVC. 而UCOSII的任务有的用SYS模式,也有用SVC移植的.两者相比有什么大的区别?最新的移植范例是SVC模式下的.


2.ATPCS规定的ARM堆栈是8字节对齐.但是IAR中可选4字节.平时操作堆栈好象也是4字节对齐?


3.在Atmel前后台的irq处理中irq堆栈只保存了3个寄存器(LR_irq, SPSR_irq, R0),八级嵌套的话最多是3*8*4 = 96字节.
而且ISR是切换到SVC模式下去执行的.其他的内容保存在SP_svc的任务栈中.保持了I和F的畅通,能被irq继续中断.
但UCOSII中好象都是使用的irq模式去处理ISR,这样有个好处是不用每个任务都留出一段任务栈.统一保存到irq堆栈.但是好象所有例程在跑ISR时都把I屏蔽了..那么就不能进行中断嵌套了..? (在IRQ模式下如果I没被屏蔽应该还可以继续被IRQ中断吧)


4.在原S64的启动代码主要完成了几个事. A.初始化临时堆栈进行lowlevelinit (禁止WDT,配置正确的时钟,配置中断源)
                        B.初始化irq堆栈到ramend.初始化SVC堆栈到ramend-96
                        C.初始化变量段.跳转main
在UCOSII移植中,原来2.76版是差不多的.但是2.83新的版本移植有几个变化. 
  1)采用了可以跳转+/-4GB的方法. 用PC装载一个32位地址(B跳转当前+/-32M已经足够)
  2)对堆栈的初始化不同.主要和后面用的模式.和中断的处理有关.但是好象没有用到ramend
  3)没有进行lowlevelint配置中断源和系统时钟配置,是运行到bsp_init()才做的.那么之前用的应该是32768的内部时钟.
  4)但是bsp_init()中有一个OS_CPU_InitExceptVect.直接把地址进行操作.这应该是重映射后才能用,但是例程没用重映射也能跑.不出错?. 


5.IAR中的Plug-in UCOSII插件是免费的还是?,需要加入什么新的模块?怎样去使用它.
uc-Probe和uc-View的话又是怎样弄的.搭建嵌入式平台的话需要这个东西


6.uC/CPU和uc/LIB有什么用?       

: ) 请大家帮帮忙.我主要是中断那块和几个堆栈的容量分配不太清楚..

使用特权

评论回复
12
ayb_ice| | 2008-2-16 13:39 | 只看该作者

自己移植还是要有相当的水平的

使用特权

评论回复
13
machunshui| | 2008-2-16 14:38 | 只看该作者

理解不充分,随便说说

1.sys模式和svc模式都是特权模式,操作权限都不受限制。
svc模式是软件中断后进入的模式,是一种异常模式,有自己的LR和sp,是供操作系统使用的模式。

sys模式一切等同于user模式,但是具有user没有的特权,例如user模式下不能进行arm模式切换,但是sys模式下可以。

sys模式用于具有特权的操作系统任务。

使用特权

评论回复
14
machunshui| | 2008-2-16 16:22 | 只看该作者

好像应该能实现中断嵌套

"但UCOSII中好象都是使用的irq模式去处理ISR,这样有个好处是不用每个任务都留出一段任务栈.统一保存到irq堆栈.但是好象所有例程在跑ISR时都把I屏蔽了..那么就不能进行中断嵌套了..? (在IRQ模式下如果I没被屏蔽应该还可以继续被IRQ中断吧)"

用户的isr切换到系统模式并开中断应该能实现中断嵌套。
不过话说回来,用OS还进行复杂的中断嵌套,好像有些不统一,不协调。

isr尽量短小,是必要的。

使用特权

评论回复
15
machunshui| | 2008-2-16 16:29 | 只看该作者

其实,看清楚任务切换,就可以了

其实,看清楚中断任务切换,就可以了。

主要还是要熟练运用,熟练掌握ucos的任务同步通信机制,并灵活运用。
周航慈编的一本书,专门讲ucos的编程使用,很不错。
正在看.

使用特权

评论回复
16
Swd21ic|  楼主 | 2008-2-16 20:34 | 只看该作者

Re

我有老周那本书..讲的还可以.
设计思想和以往的前后台有很大不同..

svc是软中断后的模式..  
iar移植时并没有使用软中断..
直接使用BL调用了任务切换的汇编函数..

你所的sys与svc的区别我知道 ..不过两种移植方式实际有什么区别就是搞不清.呵呵

要弄清移植的每个细节还是有点麻烦..

使用特权

评论回复
17
machunshui| | 2008-2-16 21:46 | 只看该作者

以前没注意中断嵌套的问题

以前没注意中断嵌套的问题.
和你讨论后,又看了zlg的移植,发现zlg的移植中断嵌套好像有漏洞.

两种移植,对使用来说区别不是很大.
zlg的移植可以普通任务切换和中断级任务切换公用一个切换子程序.

使用特权

评论回复
18
armecos| | 2008-2-17 00:05 | 只看该作者

象AT91这类芯片比较适合跑ecos之类的

    深度嵌入式系统。bootloader、TCP/IP协议栈、文件系统、GUI、USB等都是现成的。ucos只是一个系统核心,你自己做外围的软件部件的话,难度太大。
    
    ecos中断采用ISR + DSR方式,大大减少了最大中断延迟,ISR部分可以做得很小,重负荷的中断处理工作甩给DSR即可,避免在ISR里停留过久。不采用中断嵌套方式,而是在DSR里切换中断任务,减少了中断处理时间的不确定性。理论上,ucos的ISR无论如何也不可能比ecos的小。
    
    ecos的中断处理是万能的,抽象程度很高,适合各种体系架构。
    
    详见:快快乐乐跟我学嵌入式

使用特权

评论回复
19
Swd21ic|  楼主 | 2008-2-17 12:23 | 只看该作者

Re

ZLG不做AT..看了也没用..
MCZONE有个家伙改了下中断的移植..我正在看.大概思想也很像..

楼上的兄台.ecos用c++写的我看不懂... 有空可以学学...

使用特权

评论回复
20
machunshui| | 2008-2-17 18:19 | 只看该作者

学学 linux驱动编写

没那么大精力学ecos了.
学学 linux编译,配置裁减,驱动编写,倒是可以尝试一下.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

71

主题

781

帖子

1

粉丝