完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 一只耳朵怪 于 2018-6-22 09:23 编辑
Starterware工程与自建工程默认ARM Mode的区别由来 3-22-2016 Tony Tang 针对有不少用户对ti提供的starterware工程,以及自建的CCS工程里的ARM模式存在疑问,觉得有必要做个简单总结,以理清思路,节省大家的时间为目的。 #1. ARMV4以上的内核有7个不同的模式,其状态可以通过CPSR寄存器确定。(至于为什么要分这么多种模式,不是本小结的讨论内容) (1) User Mode:用户模式。操作系统的Task一般以这种模式执行。User Mode是ARM唯一的非特权模式,这表示如果CPU处于这种模式下,很多指令将不能够执行,因此操作系统的资源得以保护。 (2) System Mode:这是V4及其以上版本所引入的特权模式。、 (3) IRQ Mode:中断模式。中断(不包括软中断)处理函数在这种模式下执行。 (4) FIQ Mode:快速中断模式。除了多了几个寄存器外,其他同IRQ一样。 (5) Supervisor Mode:管理模式。软中断(SWI)处理函数在这种模式下执行。 (6) Abort Mode:所有同内存保护相关的异常均在这种模式下执行。 (7) Undefined Mode:处理无效指令的异常处理函数在这种模式下执行 #2. ARM在不同的模式下有不同的权限,以OMAP-L138为例,修改系统寄存器需要在supervisor或system mode这种privilege模式下才行,比如配置PLL,PINMUX等。 #3. 大家发现用starterware提供的工程,一切都是那么顺利,似乎这些模式与自己无关,所以从未关心过。但是一旦自己用CCS新建一个工程,就什么也配置不了了,一看CPSR原来是在用户模式,但怎么进入privilege模式呢~~~ #4. 百度~~~ARM在user mode下要通过SWI才能进入supervisor模式,spnu151L文档里也提供了call_swi()函数接口,还可以带个参数,可是为什么一调用就跑飞了呢?还有这个参数是啥意思? #5. 不管查什么资料,基本上都说ARM上电启动后是supervisor模式,而且上电后连上仿真器,也可以看到CPSR显示的是supervisor模式。可是运行到main就变成user mode了,那么在main之前干了啥~~~ #6. C工程从来都不是从main开始运行的,注意到map文件没,里面的entry_point是_c_int00, 如果不知道它是干啥的,看一下spnu151l的第6章,简而言之,就是C环境初始化,(写汇编可从来没这个说话). 还是看看_c_int00这个函数做了啥吧(这个函数在RTS库里,源文件在CCS的编译器安装目录下boot.asm)。 ;*------------------------------------------------------ ;* SET TO USER MODE ;*------------------------------------------------------ MRS r0, cpsr BIC r0, r0, #0x1F ; CLEAR MODES ORR r0, r0, #0x10 ; SET USER MODE MSR cpsr_cf, r0 简单来看,就在这里切换到了user mode,然后初始化了user mode的堆栈,再是对初始化段做初始化(__TI_auto_init),再就跳到我们的main了 ;*------------------------------------------------------ ;* INITIALIZE THE USER MODE STACK ;*------------------------------------------------------ .if __TI_AVOID_EMBEDDED_CONSTANTS MOVW sp, __stack MOVT sp, __stack MOVW r0, __STACK_SIZE MOVT r0, __STACK_SIZE .else LDR sp, c_stack LDR r0, c_STACK_SIZE .endif ADD sp, sp, r0 ;*----------------------------------------------------- ;* ALIGN THE STACK TO 64-BITS IF EABI. ;*----------------------------------------------------- .if __TI_EABI_ASSEMBLER BIC sp, sp, #0x07 ; Clear upper 3 bits for 64-bit alignment. .endif ;*----------------------------------------------------- ;* SAVE CURRENT STACK POINTER FOR SDP ANALYSIS ;*----------------------------------------------------- .if __TI_AVOID_EMBEDDED_CONSTANTS MOVW r0, MAIN_FUNC_SP MOVT r0, MAIN_FUNC_SP .else LDR r0, c_mf_sp .endif STR sp, [r0] ;*------------------------------------------------------ ;* Perform all the required initilizations: ;* - Process BINIT Table ;* - Perform C auto initialization ;* - Call global constructors ;*------------------------------------------------------ BL __TI_auto_init ;*------------------------------------------------------ ;* CALL APPLICATION ;*------------------------------------------------------ BL ARGS_MAIN_RTN #6. 怎么办,最简单的办法就是把这个文件加到工程里去,然后把切换模式这段代码删掉就行了(因为在工程里源文件与库文件存在同样的lable,会优先调用源文件的),但是后面想切换到user,又想从user切换到supervisor怎么办呢,再说吧~~~。 #7. 现在再来看看starterware的工程,注意一下cmd文件,里面都加了一句-e Entry,也就是说starterware的工程不是从_c_int00开始执行的,所以编译输出信息里也相应多了一句警告,这没关系,只要在main之前把该做的做了就行,_c_int00只是提供了一个简便的现成的函数,因为通常都是做同样的事件,没必要大家每次自己写一遍嘛。 #8. 对比一下Entry与_c_int00的区别吧。Entry在starterware的system_configarmv5下对应的编译器类型目录下的init.asm文件,
#9. 至于上面那个数组的trick,在内存上显示其代表的汇编就明白了,它巧妙的在向量表上加上了跳转到各异常向量的处理handler(这要通过对指定格式的了解才能整出这么个数值来): 后面带着system mode进入main后,就由用户自由发挥了。但是这里跟前面那个改boot.asm进入main后的区别是什么呢?前面我也提到如果想进切换模式怎么办。 现在的基于starterware的工程可以调用cpu.c文件里的函数进行模式切换,但是前面那种修改的工程是不行了,一调用就跑飞。原因在于,在调用swi时,程序会跳转到SWI位置即0xFFFF0008, 然后跳转到SWIHandle(见exceptionhandler.asm), SWIHandler: STMFD r13!, [r0-r1, r14] ; Save context in SVC stack LDR r0, [r14, #-4] ; R0 points to SWI instruction BIC r0, r0, #MASK_SWI_NUM ; Get the SWI number CMP r0, #458752 MRSEQ r1, spsr ; Copy SPSR ORREQ r1, r1, #0x1F ; Change the mode to System MSREQ spsr_cf, r1 ; Restore SPSR LDMFD r13!, [r0-r1, pc]^ ; Restore registers from IRQ stack 这里就进入了supervisor mode,而且对传进来的参数做了对比确认,理论上可以做一长串的参数对比,做不同分支的处理。 为什么自己建的CCS工程不行呢,因为还没有做异常向量表的初始化,调用SWI时,系统自动跳转到0xFFFF0008,谁知道这时候这地方是一条什么指令呢,所以在调用之前必需要先初始化异常向量表等等,有兴趣自己实现吧。 附上我基于starterware简化过来的工程。 http://processors.wiki.ti.com/index.php/Main_Page Think Over Before Asking. http://www.catb.org/~esr/faqs/smart-questions.html#goal |
|
相关推荐
9个回答
|
|
好贴,加精。
只可惜附件工程导入失败:提示 See details below. Error: Import failed for project 'arm9_previlege_Mode' because its meta-data cannot be interpreted. Please contact support. |
|
|
|
我是用CCSV6. Version: 6.1.2.00015建的工程。目前电脑没装CCSV5. http://processors.wiki.ti.com/index.php/Main_Page Think Over Before Asking. http://www.catb.org/~esr/faqs/smart-questions.html#goal |
|
|
|
lifei639156 发表于 2018-6-21 00:58 上传一个我的CCS V5.5下面的最小工程,供大家参考 其中: arm端,使用定时器点了个灯,一秒一次。 dsp端,带dsp/bios系统,点灯,同样一秒一次。 |
|
|
|
学习了。
另外: 文中提到的,spru151L文档 应该是spnu151L(ARM Optimizing C/C++ Compiler v15.12.0.LTS User's Guide)吧。 |
|
|
|
yh3091876423 发表于 2018-6-21 01:25 谢谢提醒,已更正。 http://processors.wiki.ti.com/index.php/Main_Page Think Over Before Asking. http://www.catb.org/~esr/faqs/smart-questions.html#goal |
|
|
|
写的非常好,如果早3年看到这篇文章,当时就不会绕太多弯路了
|
|
|
|
你好,我将startware的工程移植到 CCS3.3环境下,编译提示 找不到 __TI_auto_init ,请问是要添加哪个库呢?
|
|
|
|
上面总结里说了,这是RTS库里的函数,了解一下什么是RTS库: 上面的_TI_auto_init还是一样调用的RTS库的,然后调用了start_boot(startup.c), http://processors.wiki.ti.com/index.php/Main_Page Think Over Before Asking. http://www.catb.org/~esr/faqs/smart-questions.html#goal |
|
|
|
我在我自己新建的工程里面添加的 -e Entry 编译出错,请问是什么原因?
|
|
|
|
只有小组成员才能发言,加入小组>>
299 浏览 1 评论
508 浏览 2 评论
NA555DR VCC最低电压需要在5V供电,为什么用3.3V供电搭了个单稳态触发器也使用正常?
745 浏览 3 评论
MSP430F249TPMR出现高温存储后失效了的情况,怎么解决?
636 浏览 1 评论
对于多级放大电路板,在PCB布局中,电源摆放的位置应该注意什么?
1105 浏览 1 评论
请问下tpa3220实际测试引脚功能和官方资料不符,哪位大佬可以帮忙解答下
220浏览 20评论
请教下关于TAS5825PEVM评估模块原理图中不太明白的地方,寻求答疑
177浏览 14评论
两个TMP117传感器一个可以正常读取温度值,一个读取的值一直是0,为什么?
44浏览 13评论
在使用3254进行录音的时候出现一个奇怪的现象,右声道有吱吱声,请教一下,是否是什么寄存器设置存在问题?
148浏览 13评论
TLV320芯片内部自带数字滤波功能,请问linein进来的模拟信号是否是先经过ADC的超采样?
151浏览 12评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-15 18:54 , Processed in 1.297051 second(s), Total 93, Slave 77 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号