2009-10-10
评论1
楼主 2009/10/10 22:00:52
第76 问:
Q:我想使用标准C 语言的库函数,比如memset 在string.h 中有定义,可是我直接包含
#include , 但是编译没错误,运行确有错误,应当怎么设置
A:请使用最新的工程模板
第77 问:
Q:软件中断是不是必须由SWI 指令触发
A:可以直接用你定义成软中断的函数名啊.比如:
19
__SWI(0x12) void myswi(void); // 声明函数
__asm // 调用方式1
{
swi 0x12
}
myswi(); // 调用方式2
第78 问:
Q:《ARM 微控制器基础与实战》程序清单6.9 的程序是在哪里被调用的
_user_initial_stackheap
LDR r0,=bottom_of_heap
MOV pc,lr
A:__main.千万别删哟, 否则出大事的.
第79 问:
Q:"LDR R0, =PINSEL0" 中"="是什么意思 这语句是取地址还是取地址中的内容呢
A:这是LDR 伪指令,可用来加载32 位立即数或地址,LDR R0,=PINSEL0 是将PINSEL0 的地
址加载到R0 中.
第80 问:
Q:我不明白"SWI 0"和"SWI 0X123456"这两条指令中的0 和0X123456 中有何用.
有没有应用SWI 的具体例子让我看看
A:那是特定的中断入口地址,见ADS_DeveloperGuide_D.pdf 下的swi.
第81 问:
Q:SWI 的功能表吗
A:SWI 的功能表由swi 异常服务程序决定.很多时候由编程者自己决定.
第82 问:
Q:请问:我在实验您的原代码进行ucos 移植时用的是例1,但是在按照图7.17 设置处理
器的仿真器模式时enable comms channel view 和semihostin 项为不可激活状态.为
什么,能否给一点提示
A:在一些仿真器上使能了它们会影响swi 异常处理程序.
第83 问:
Q:请问"Unimplemented RDI message"这个出错提示是什么意思啊
20
还有,有的时候当我用axd load 一个.axf 文件时,常常loading 的没完没了,这是怎
么回事啊
A:Unimplemented RDI message:为命令操作失败,需要重新连接.
下载不结束为出现不正常现象,请重新连接并下载.如果每次都出现该现象请联系我们
的技术支持.
第84 问:
Q:各位高手好,我是ARM 初学者我在程序调试中"LDR PC,[PC,R2]"命令执行后PC 为什么
=0x0000000c, 在这条命令执行前PC+R2 地址上的值是0x0000000c 吗
A:要使用软件仿真.0x0000000C 是预取中止了.
Q:请问:ARM7 在初始化CPU 堆栈时,寄存器CPSR 和CPSR_c 有什么关系 CPSR_c 是在那里
定义的
A:这是MSR 指令的语法,"_"后部分指定CPSR 的域,请参考《ARM 微控制器基础与实战》
上关于这条指令的说明.
第85 问:
Q:软中断SWI 作底层接口的问题.以下函数为啥要通过软中断调用,可以直接调用吗
OS_TASK_SW(),
_OSStartHighTdy(),
OS_ENTER_CRITICAL),
OS_EXIT_CRITICAL(),
A:在用户模式或Thumb 状态不能直接调用.
第86 问:
Q:ARM 的一条指令是32bit 长, 但有时一个立即数也是32bit, 这是如何解释的
A:指令中使用的立即数需要时8 位数移位获得,并非所有数都可以.
第87 问:
Q:请教:全局变量的值在复位(不断电)后会不会自动清零 (用光盘自带的启动代码)
A:在C 语言中一般会会初始化0 或用户指定的值,但这不是硬件自动的.
第88 问:
Q:the setting files for *.mcp is locked!是什么问题
A:文件属性只读.
第89 问:
21
Q:请问,关于printf() 在ads 中怎么用不了 谢谢!
A:请用我们我们网站上下载2104 的工程模板,它解决了这个问题.
即使这样,也不能真正使用prinf.您还需要自己编写一些底层函数才能使用,详细参
考ads 自带的ADS_CompilerGuide_D.pdf.
第90 问:
Q:swi 的功能号是如何来的 它和LR 寄存器的值是何关系
如《ARM 微控制器基础与实战》程序清单6.13
LDREQ R0,[LR,#-4] ;BICEQ R0,R0,0xff000000
A:LDREQ R0,[LR,#-4] ;用来读SWI 的代码
BICEQ R0,R0,0xff000000 ;是ARM 方式进入,取低24bit
第91 问:
Q:请问在TargetInit()中函数开始会执行srand((INT32U)TargetInit),它是做什么用的
A:ex1 用它来产生随机数种子的.
Q:请问:我建立的工程中,所有源文件与2104 附带的光盘例子源文件相同,编译链接也一
切正常, 可就是不能到板子上跑!
提示错误是:向量中断有错误,无法自由运行!!
这是怎么回事 相同的源文件,加在你的工程里,正常;加到我的工程中就出错!
我创建的是ARM 可执行映象.
A:vector.s 你自己的吗 如果是要计算向量去的累加和了.
第92 问:
Q:请问:vectors.s 中"DCD 0xb9205f80" 的0xb9205f80 在实际运用中需要改动吗
A:不需要更改,除非改动了向量表中的指令代码.
第93 问:
Q:请问,为什么queue 数据队列,《ARM 微控制器基础与实战》上给画成了环形
A:因为头跟尾的指针指向一个地址,队列逻辑上是环状的.
第94 问:
Q:有没有人成功的把一个数据定义到程序空间里 各种方法我都试了,是不是有什么编译
开关
A:使用const 修饰,定义变量时带初始化值,要定义为全局的变量.
第95 问:
Q:ads 里没有CODE 关键词,怎样使定义的字符串数组不占用RAM 空间
22
A:const unsigned char string[]
第96 问:
Q:在例程中TIME_test 中的TIMEOUT 当写入时提示:
Warnning! interrupt vectors data is not correct!
Program you downloaded can not run freely!
我不知怎样改设置,哪位提醒一下
A:中断向量表的校验和不为0,用AXD 看0 地址的数据(32 位方式),自己加一下.注意把
高于32 位的部分去掉.
第97 问:
Q:请教各位:我做TIMEOUT 实验(2104 板),Make 通过,Debug 时出现了如下错误提示:
Warnning! interrupt vectors data is not correct!
Program you downloaded can not run freely!
设置Link:ARM Link
r0 base:0x00000000
rw base:0x40003000
image entry point:0x00000000 其它的没变!!
而我使用ISP 完全可以下载而且可以运行!这可以说是设置问题,但是我实在找不到!
怎么办
A:请看一看配套《ARM 微控制器基础与实战》附录1,ISP 软件可能对它进行了处理,而JTAG
没有特殊处理
第98 问:
Q:*(volatile unsigned int *)是什么意思 例如*(volatile unsigned int *)addr 具体
是什么意思
A:分开来看,(volatile unsigned int *)就是定义一个可变的无符号整形指针,前面的那
个*就是取起内容.
第99 问:
Q:如何理解#define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000))
A:宏定义,参考C 语言的书籍.
(volatile unsigned long *) 0xFFFFF000 将0xFFFFF000 强行转换为指针,然后 *(指
针) 即可对此地址进行访问.
第100 问:
Q:在异常处理向量表的设置中,为什么不直接将异常向量的入口地址写入PC 中呢,为什么
非要用什么DCD 这些伪指令,到底有什么用啊
A:为了保证任何时候其累加和为零,不然改一次程序就要计算一次.
23
第101 问:
Q:单步调试i2cINT.C 在ISendStr 中启动总线后,程序怎么又跑到vectors.o 中,进行初
始化了呢
A:由于VIC 的限制,程序不能在0x18 停下来,否则执行非向量中断.如果没有设置,则非
向量中断为0,将从0 地址执行.
建议:有中断时不要单步执行程序,可以手动暂时关中断或设置断点代替单步.
(编者注:下载最新的驱动可以解决这个问题)
第102 问:
Q:请教:如何修改 ADS 的启动代码,从__main 到main,按道理应该有一个文件,修改这
个小文件, 就可以修改 启动代码.
A:__main 是ADS 运行库,最好不要修改,要是不使用库就不要用main()函数,起个别的名
字.直接跳转过去就行了.
详见:《ARM 体系结构与编程》P328.
第103 问:
Q:我在JTAG 仿真时出现的对话框,提示:
Warnning! interrupt vectors data is not correct!
Program you downloaded can not run freely!
A:参见《ARM 微控制器基础与实战》附录一第一个问题的第二部分,选择源代码的启动代
码文件夹下的vectors.s,并参照《ARM 微控制器基础与实战》图7.11 设置.
第104 问:
Q:初始化代码中分配堆栈的问题
MSR CPSR_c, #0xd3 ;进入特定的处理器模式
LDR SP, StackSvc ;给当前处理器模式的堆栈指针赋值,这只是一个值而已,
;他在接下去的DCD 语句赋值
SvcStackSpace SPACE SVC_STACK_LEGTH * 4
这个语句开辟一个SVC_STACK_LEGTH * 4 大小的内存,SvcStackSpace 是这块内存的标
号,我想应该就是内存的首地址,这样应该好理解了.
StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
这个语句就是把这个首地址加上堆栈大小值.
A:计算出堆栈指针来,我想这个堆栈是向下生长的,所以SP 赋值的是堆栈地址最高的那个.
第105 问:
Q:请问启动代码中这句是什么意思
24
__user_initial_stackheap
LDR r0,=bottom_of_heap
MOV pc,lr
;/* 分配堆空间 */
AREA Myheap, DATA, NOINIT, ALIGN="2"
bottom_of_heap SPACE 256 ;库函数的堆空间
我的问题是:
1.这个函数在哪里被调用
2.赋值给r0 以后就完事了 r0 起什么作用
A:堆和栈的分配函数,由ADS 提供的初始化代码调用,具体参考配套《ARM 微控制器基础
与实战》的相关部分.
第106 问:
Q:2104 的启动代码是否适用2124 呢
网站上下载的那个easyarm2104 工程模版里面写着arm executable imag for lpc21**,
是否说也适用2124 呢 如果不行,哪些地方需要修改 希望能够指点一下!
A:您可以下载2100 的工程模板.
第107 问:
Q:我在用ARM 的IAP 功能,要把已经烧到flash 中的数据写到RAM 中,我是这么写的:
uint32 *q,data;
q = 0x00006000;
data = *q;
这是要读的flash 的起始地址,但是第二句编译出错,我想应该是C 编译器不许给指针
直接赋值, 我用汇编解决了这个简单的问题,但是怎么用C 来解决呢
A:q = (uint32 *)0x00006000;
第108 问:
Q:问一个有关汇编的基础问题.
例程: ANDS R1,R1,#0x0400
BEQ WAITOK
请问 ANDS 是如何影响标志位的,而BEQ 判断的是那两个操作数相等时执行
A:R1&0x0400 => R1,若结果为0(即R1 为0),则标志位Z=1.
当Z=1 时,BEQ WAITOK 有效执行.
第109 问:
Q:请教:在ADS 中怎么给某个变量确定固定物理地址
就是类似KEIL 中的 XDATA xxx _AT_ 0x4456 的功能.
A:使用分散加载机制,mem_c.scf 等就是例子.
25
第110 问:
Q:哪里有介绍ARM 的C 语言编程的
A:其实大多数嵌入式系统的C 语言都差不多,可找一本写嵌入式C 语言的书即可.
第111 问:
Q:请问在系统复位后首先执行的是否为Boot Block 的中断向量
然后由boot block 里面的程序决定是执行用户程序还是ISP 程序.
那么这时启动的boot block 里的中断向量表和用户程序里的中断向量表是如何在flash
里安排的
在《ARM 微控制器基础与实战》上看到的是复位后boot 扇区的最低64 字节出现在
0x00000000 区域,那用户的中断向量表应该在哪个区域
产品中一般为0x00000000,在开发板中重启后实际为boot block 的中断向量地址,对
吗
A:看一看3.3.6 节.产品中一般为物理0 地址处.
第112 问:
Q:《ARM 微控制器基础与实战》上有一段程序:
uint32 i;
i = VICIRQStatus;
i = IOSET;
请问:为何先要读取VICIRQStatus 的值,才能读IOSET 的值
A:读出VICIRQStatus 只是为了方便观察当前VICIRQStatus 的值,没其它用途.
第113 问:
Q:请问处理器在什么情况下处于用户模式 多谢!
A:需要你去设置CPSR 寄存器.
用户程序前台程序一般在用户模式/系统模式下运行.
第114 问:
Q:在EINT1_LED.S 中的倒数第二行有一个单独的B 指令,它是什么含义 多谢!
A:是"B .",跳转到当前地址,即死循环,与以下代码等效:
HALT B HALT
第115 问:
Q:模板里到底有些什么
A:起动代码,相关编译链接设置.
起动代码是用来初始化系统的程序,如Startup.s,target.c,stack.s 等等.
26
第116 问:
Q:今天试用了工程模板.使用了ARM Executable Image for lpc21xx 建了个项目,看了下
启动文件与原来的不同了,用了个《ARM 微控制器基础与实战》上的例程来作试验,用
的是time0 定时中断来亮灯的程序,用的例程的TargetInit()和int main(void);
修改了用户堆栈和bottom_of_heap 的长度,程序能运行,但不能产生中断,time0 和VIC
初始化的是正确的,是什么原因
用工程模板建立的项目文件夹的src 中多了几个文件,其中的
mem_a.scf,mem_b.scf,mem_c.scf,怎样才能导入到项目中来 谢谢!
A:原来startup.s 默认是关了中断的!
第117 问:
Q:在easyarm 2104 的配套光盘中的IAP 例子中,定义了一个函数指针
void (*IAP_Entry)(uint32 param_tab[], uint32 result_tab[]);
我看不懂,这个函数和普通的函数定义方法不一样,尤其是(*IAP_Entry),大家教教我.
A:这是一个指向函数的指针!!
第118 问:
Q:变量定义中volatile 是什么意思 请大侠告诉我一下《ARM 微控制器基础与实战》上c
语言定义变量时出现了volatile,不知道是做什么用的.C 语言里好像没有这个语法阿!
A:告诉编译器不要优化掉,volatile 是易变的意思.
第119 问:
Q:请问ARM 中的一个编译方面碰到的问题.
在ARM 地汇编语言中,有条件编译伪指令IF..ELSE...ENDIF;
而在C 语言中,有相应的条件编译伪指令#IF...#ELSE...#ENDIF,在较大的程序设计中,
往往需要对整个程序进行条件编译.
我要问的问题是:我在CONFIG.H 中设置一个编译开关,对所有的C 文件进行条件编译是
有效的, 因为每个C 文件中都有一个语句:#include "config.h",我如何将该编译
开关的信息传递给汇编语言文件,如VECYORS.S
A:好像没有直接的方法,可以编写一个CONFIG.INC 来管理汇编程序的配置.
27
第3 章 操作系统
第120 问:
Q:在SWI_Exception 的0x40 中的_OSFunctionAddr[regs[0]]中的Regs[0]指的是堆栈中的
R0 还是其它
A:是堆栈中的R0.
第121 问:
Q:《ARM 微控制器基础与实战》中在ucos 移植中说C 语言无法保证堆栈的结构,请问这是
什么含义
A:就是不能保证有哪些寄存器入栈及寄存器入栈的顺序.
第122 问:
Q:请问斑竹OSNeedToSwapContext 在哪个文件里声明的,我找不到
A:这是要删除的,我的OS_CPU_C.C 中函数OSIntCtxSw:
/*
***************************************************************************
* 函数: OSIntCtxSw.
* 描述: 中断级任务切换,此处并不真正进行任务切换,具体切换在 IRQ 服务程序中.
***************************************************************************
*/
void OSIntCtxSw (void)
{
}
第123 问:
Q:我的情况如下:我自己制作了一个硬件模块,用的是lpc2214,现在需要将ucos-ii 移
植到上面去.我用板子做ZLG 公司提供的实验,是可以做的,如led 灯等,按道理说串
口等硬件应该没有问题,然后我就做公司提供的那三个移植实例:ex2_arm.编译等是通
过的,生成了hex 文件,下载到flash 中,运行easyarm,但是没有任何显示,不知道是
什么问题,应该是硬件上呢,还是其他的
A:这主要是RAM 的问题,请用我们的工程模板,并选择在FALSH 中调试,如果编译通过,
则一般行, 否则请减少任务堆栈的大小.
第124 问:
Q:下载了工程模板以后,将工程模板目录下的文件都拷贝到了stationary 目录下,然后建
立了一个 ARM Executable Image for UCOSII(for lpc21xx)的工程,在PROJECT 目
录下的文件结构如下:
28
test.c
inlcudes.h
src->config.h,heap.s,includes.h,irq.s,lpc2294.h,
lpc2106.h,mem_a.scf,os_cfg.s,stack.s,startup.s
target.c,target.h,ucos_ii.c,ucos_ii.h,
arm->os_cpu.h,os_cup_a.s,os_cup_c.c
uCOS->ucos 源文件
arm_pc->pc.h,pc.c
编译可以通过,但是MAKE 时提示:
ERROR:Execution region IRAM overlaps with Execution region STACKS.
如果我表述得不是很清楚的话,那么可否告诉我工程模板到底怎么操作,怎样才能把例
子在 ARM2104 上跑起来.
A:RAM 占用太大,请在flash 中调试,并减少任务堆栈的大小.
第125 问:
Q:我改了以下SCF 文件,把堆栈的值设置大了一些,但是还是出现以前的老问题,那就是
程序跑到
TargetResetInit()函数处后就跳到取数据终止的异常中断去了.
A:不能把堆栈设置到内部RAM 之外.
第126 问:
Q:新旧任务级的切换是不是必须在管理模式下切换 切换后新任务的运行是不是必须在管
理模式下
A:在配套《ARM 微控制器基础与实战》里的任务切换是通过SWI 实现的.SWI 会使CPU 进入
管理模式.同时CPU 自动将任务的CPSR 保存到管理模式的SPSR 中.
SWI 程序还保存了一些寄存器到管理模式的堆栈中.然后任务切换程序会在管理模式
和系统模式间来回切换,目的是把保存在管理模式堆栈的寄存器内容拷贝到任务的堆栈
中(注意:任务是运 行在用户模式或系统模式的,这两个模式使用同一个SP,这时的
系统模式的SP 指向的就是任务的堆栈),也会将管理模式的SPSR 拷贝到任务堆栈(注意
管理模式的SPSR 就是在执行SWI 时CPU 自动保存的任务运行时的CPSR,它记录了任务
运行的CPU 模式和其他的运行状态信息).最后把任务模式SP 保存到任务的任务控制块
中(注意此时CPU 已经是运行在系统模式下的了).以上大致就是uC/OS-II 中所说的保
存任务运行环境的工作.
任务的恢复运行就比较好理解了.
接着前面的说,CPU 还在系统模式下.程序从任务控制块中得到任务的堆栈指针.
(OSIntCtxSw_1 的第一句)将这个指针的值加上一定的偏移量保存到SP 中.为什么要
加上一定 的偏移量呢 因为这时任务的堆栈中除了保存任务运行时的数据外还保存
了任务的上下文,即任 务切换时保存的CPU 寄存器等内容.而我们恢复任务等一下是
在管理模式下进行的,用的是管理模式的堆栈指针.等恢复任务后CPU 就开始执行任务
29
代码了.我们已经没有机会再修改系统模式下的SP 值了.所以在这个时候就应该对SP
进行调整.调整的大小就应该是所保存的上下文占用的大小.从堆栈中恢复LR 的值.同
样的道理,管理模式和系统模式使用不同的LR,在切换到管理模式之前,必须先在系统
模式下恢复任务运行时的LR.(OSIntCtxSw_1 的第三句)接下来就切换到管理模式了.
(OSIntCtxSw_1 的第四句)使管理模式SP 指向任务堆栈(第五句)注意这是没调整过
的任务SP,也就是保存了上下文环境的SP.
接下来的事情就真的很简单了.从堆栈中恢复出保存的东西.先是OSEnterSum,然后是
任务的CPSR (注意任务的CPSR 就是进入SWI 时由CPU 自动保存到管理模式的SPSR
中的,所以此时也是恢复到管理模式的SPSR 中)最后一句就是典型的中断返回语句了.
恢复寄存器,恢复PC,加了一个^号意味着同时将SPSR 拷贝到CPSR 中.
现在是回答你的问题的时候了.
切换前任务是运行在什么环境下的(包括CPU 模式,所有的寄存器),任务切换后任务就
是运行在 什么环境下的.对任务来说,什么也没改变.只有PC 值指向了下一条指令,
哈哈.
第127 问:
Q:请教:在rtos51 解释的概念里的"信号量"比较难懂,"消息队列"可以理解为任务之间
互相传递的参数,但"信号量"怎样理解呢 具体一点,谢谢!
A:信号量是60 年代中期Edgser dijkstra 发明的,它实际上是一种程序间的约定机制,
这种约定决 定那个程序(任务)可以执行.在多任务内核中普遍使用信号量用于:
1.控制共享资源的使用权(满足互斥条件);
2.标志某事件的发生;
3.使两个任务的行为同步.
信号量像是通行证,且通行证的数目是有限的.任务要运行下去,要先拿到通行证.如
果信号量 已被别的任务占用,该任务只得被挂起,直到信号量被当前使用者释放掉.
信号量的值可以是0 到255 或0 到65535,或0 到4294967295,取决于信号量规约机制
使用的是8 位,16 位还是32 位.到底是几位,实际上是取决于用的那种内核.根据信
号量的值,内核跟踪那些等待信号量的任务.
一般地说,对信号量只能实施三种操作:初始化,也可称作建立;等信号也可称作挂起;
给信号或发信号.信号量初始化时要给信号量赋初值,等待信号量的任务表应清为空.
想要得到信号量的任务执行等待操作.如果该信号量有效(即信号量值大于0),则信号
量值减1,任务得以继续运行.如果信号量的值为0,等待信号量的任务就被列入等待信
号量任务表.多数内核允许用户定义等待超时,如果等待时间超过了某一设定值时,该
信号量还是无效,则等待信号量的任务进入就绪态准备运行,并返回出错代码(指出发
生了等待超时错误).任务以发信号操作释放信号量.如果没有任务在等待信号量,信号
量的值仅仅是简单地加1.如果有任务在等待该信号量,那么就会有一个任务进入就绪
态,信号量的值也就不加1.于是通行证给了等待信号量的诸任务中的一个任务.至于
给了那个任务,要看内核是如何调度的.收到信号量的任务可能是以下两者之一:
1.等待信号量任务中优先级最高的任务;
2.最早开始等待信号量的那个任务,即按先进先出的原则(FIFO).
30
有的内核有选择项,允许用户在信号量初始化时选定上述两种方法中的一种.但Small
RTOS51 只 支持优先级法.如果进入就绪态的任务比当前运行的任务优先级高(假设,
是当前任务释放的信号量激活了比自己优先级高的任务).则内核做任务切换(假设,使
用的是占先式内核),高优先级的任务开始运行.当前任务被挂起.直到又变成就绪态中
优先级最高任务.
第128 问:
Q:我用了两个串口,但当我把程序做大的时候,发现在这个任务里所建立的邮箱失败,
我只用一个串口时是没有这种事情的.
Uart0ReviceMbox = OSMboxCreate((void *)0 ); /* 建立邮箱 */
if (Uart0ReviceMbox == NULL)
{
while (1);
}
我想问一下有几种可能会造成这种分配失败 我的程序存储器用量如下:
Total R0 size 22168
Total RW size 7956
Total ROM size 22168
A:在OS_CFG.H 中定义最大事件数,太小的话,分配会失败的.
第129 问:
Q:在周立功的原例子中,系统代码事先烧到ROM 中,应用代码在RAM 中运行.我想知道,
(RAM)应用代码调用系统函数,那么2104 是如何把ROM 中的系统函数的地址传递给RAM,
也就是应用代码和系统代码是如何关联在一起的 我猜是通过swi(软中断),应用代码
通过swi 调用系统代码,但是swi 中断程序中,是如何获得烧到RAM 中的系统函数的地
址哪 百思不得其解.
A:您看一看romcode 工程中swi 的0x40 和0x41 功能,
及Os_call.c,Os_call_arm.s,Usr_call_arm.s.
第130 问:
Q:16k 的RAM,128 的FLASH ROM 跑uc/os-II 够吗 再跑点应用程序够吗
A:取决于您的应用程序对RAM 的需求,及代码量.一般程序可以.
第131 问:
Q:利用lpc2104 开发应用程序时,在Os_call_arm.s,Os_call.c 两个文件中,那几个函数
需要在汇编中实现,哪几个需要在.c 文件中实现,为什么 谢谢各位大虾 !
A:4 个以上参数用c 实现.因为通过寄存器只能传递4 个参数.
31
第132 问:
Q:如果禁止SmallRTOS51 进行中断嵌套管理(#define EN_OS_INT_ENTER 0),是否还需要
设置中断优先级寄存器IP,使得所有中断的优先级都相同(全高或全低)
A:受SmallRTOS51 管理的设置为最低优先级,不受SmallRTOS51 管理的设置其它优先级较
好.
第133 问:
Q:在OS_CPU_S.s 文件中有如下一段代码,其中有两句代码的作用不是很明白,请解说一下.
OSIntCtxSw_1
LDR R4, [R6] ;获取新任务堆栈指针
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;这两行代码有何作用呢
ADD SP, R4, #68 ;17 寄存器CPSR,OsEnterSum,R0-R12,LR,SP
LDR LR, [SP, #-8]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
MOV SP, R4 ;设置堆栈指针
LDMFD SP!,{R4, R5} ;CPSR,OsEnterSum
;恢复新任务的OsEnterSum
LDR R3, =OsEnterSum
STR R4, [R3]
MSR SPSR_cxsf, R5 ;恢复CPSR
LDMFD SP!, {R0-R12, LR, PC }^ ;运行新任务
A:这两条指令是在系统模式下恢复用户模式下的LR;可以参考配套《ARM 微控制器基础与
实战》6.4.9 节.
第134 问:
Q:我将《ARM 微控制器基础与实战》上uC/OS-II 的第一章例2 移植例在ARM2104 开发版上
实现例2 中的TEST.C 中的"#define TASK_STK_SIZE 512"改为"...256",程序编译
后,数据量低于16K,能正常运行,但运行时"Total Stack"不是256 全是1024.另
UC/OS-II 书上,第一章例2 每一个任务的堆栈都是512,为什么书上11 页"Total Stack"
是"624,1024,1024,1024,1024,1024,1024",请老师指点,万分感谢!
A:显示的是字节而定义的是字.
第135 问:
Q:可不可以把所有的任务和相关信号量(二值)在一个任务里面一起创建呢 我现在是这
样做的, 不知是不是这方面的原因 而且全部信号量是这样创建的:
XX1 = OSSemCreate(0);
32
XX2 = OSSemCreate(0);
XX3 = OSSemCreate(0);
一共创建了十个信号量,以前程序代码版本是分开写的执行起来没有问题,不知现在为
什么这样写就会出现小问题呢 这样的问题和我的任务和信号里书写位置有关系吗
A:必须在使用信号量前创建信号量.
第136 问:
Q:UCOS 在中断处理完后调用 OSIntExit(),该函数将判断是不是要进行任务切换,如果是
则调用 OSIntCtxSw()切换任务, 然后才恢复寄存器,中断返回.这样说来,在中断
返回前,已经切换到别的任务去了,在再次回到被中断的任务前,是不是一直没有中断
返回
A:如果进行任务调度,则不会执行OSIntCtxSw()后的语句,相当于中断已退出.
第137 问:
Q:最近我在学习使用SMALL RTOS 时发现一个 BUG.
任务在调用系统等待函数 OSWait(K_TMO | K_SIG,x) 后,不能在延时 x 个 ticks 后
被唤醒.
我分析了一下原因如下:
在 OS_CORE.C uint8 OSWait(uint8 typ, uint8 ticks) small 中,
case (K_TMO | K_SIG): 中执行了函数 OSTaskSuspend(OSTaskID);
( OS_CORE.C 第549 行)而此函数将延时值改为了 0!
解决办法:将此函数改用另一个函数 OS_TaskSuspend(TaskID);
并在其后加入任务切换函数 OSSched();
便能工作正常.
A:对,这是疏忽,谢谢.您的更改是对的.
第138 问:
Q:在文件Os_cpu_a.s 中的函数OSIntCtxSw 中有如下语句:
……
(1) LDR R4, [R6]
(2) ADD SP, R4, #68
;17 寄存器 CPSR,OsEnterSum,R0-R12,LR,SP
(3) LDR LR, [SP, # --8]
(4) MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式
(5) MOV SP, R4
……
(6) LDMFD SP!, {R0-R12, LR, PC }^ ;运行新任务
《ARM 微控制器基础与实战》404 页中解释:只所以要(1)(2)是因为"OSTCBHighRdy
—>OSTCBStkPtr 保存的是任务栈位置,而寄存器恢复后堆栈指针并不指向这,所以要调
33
整新任务堆栈指针." 可是将堆栈指针调整到 "新任务入栈的其它数据(见《ARM 微控
制器基础与实战》图6.3)"处后,除了取出了LR 以外并没有做 什么,而当执行了(4)
后又重新将堆栈指针指向了栈顶(即第(5)句).我认为可以将(2)省去,直接将(3)改为
"LDR LR, [SP, # 60]",而当执行完(6)后,堆栈指针就自动指向了"新任务入栈的其它
数据"处.这样修改后我运行了EX1_arm 例子,正常.
请问这利用(3)进行堆栈指针调整的原因是什么 不调整可以吗 谢谢.
A:注意不同模式有不同的SP 指针.您这样做会造成内存泄漏,长时间运行会耗尽堆栈而使
程序崩溃.
第139 问:
Q:不明白在光盘上ROMCODE/SRC/下的os_call.c 做什么用.
A:是应用程序与事先固化到flash 中的ucosii 接口的一些代码.在本例中为应用程序如何
调用事先 固化到flash 中的ucosii 的OSFlagPend 等函数的接口代码.请看配套《ARM
微控制器基础与实战》的7.4.3 节的第10 点.
第140 问:
Q:请问在OS_CORE.C 中的常数数组OSUnMapTbl[]是做什么用的
A:用来计算优先级的,查表计算比较快.
第141 问:
Q:ucos 的中断嵌套层数是否受到初始化时分配的IRQ 堆栈大小的限制 我的理解是每一次
中断需入栈的寄存器有R0-R3,R12,LR,SPSR,共7 个,如果想达到8 层嵌套的话,堆栈长
度IRQ_STACK_LEGTH 应设为56,不知这样理解对不对.
A:是,但中断至少占用8 个字,因为c 语言的中断处理函数会将一些数据压入堆栈.
要达到8 级嵌套需要的堆栈长度与具体的代码有关.
(编者注:新移植代码已有改变)
第142 问:
Q:请问:核心定时器中断不进入可能因为……
我的程序在运行一段时间以后,核心定时器中断即操作系统用的Timer0 不能进入,查发
现CPSR 的I 位为1,请教这可能是哪个原因
A:估计为开关中断次数不匹配造成.
第143 问:
Q:请问:GetOSPprioCur()函数应怎样调用 它是一个内核函数吗
为什么我在内核和任务分别编译时正常,而合到一起编译时它告警为未定义呢
同时我已给您发了一个邮件,请教如何将分别编译的程序合在一起编译的方法,请指教!
A:这是我自己编写的函数,其实就是返回OSPrioCur 的值,请参考MyFunction.c.
34
第144 问:
Q:关于不受uc/os 控制的中断:在ARM 板中,非屏蔽中断可以挂起正在执行的uc/os 任务,
除了不能使用uc/os 中的函数外,它的执行工序是不是和受管理的中断一样,先挂起当
前任务,再保存CPU 寄存,然后再执行中断ISR,完成后,内核脱离,寄存器恢复,最
后任务调度.
另外,《ARM 微控制器基础与实战》中提到不受管理的中断,它的工作是否和非屏蔽中断
一样,也可以在uc/os 正执行时发生中断.如果不同,它们是怎样工作
最好是象受管理中断一样说明一下它的工作时序!
A:必须比受管理的中断的优先级高,编写方法与没有OS 时中断的编写方法一样.
第145 问:
Q:不受uc/os-ii 管理的中断和受管理的中断是否具有相同的响应方式,即不受管理的中断
在中断 uc/os 正执行的任务后,是不是也是先挂起当前的任务,保存CPU 寄存器,再
执行中断子程序,恢复CPU 寄存器,进行最优先级任务的调度.
A:不受uc/os-ii 管理,uc/os-ii 都不知道,还有什么任务调度
Q:我知道不受管理的中断不能调用uc/os 的函数,但《ARM 微控制器基础与实战》上说:
FIQ 不受uc/os 管理,但可以用来执行紧急任务,就是说在uc/os 运行时,不受uc/os
管理的中断还是可以发生的,它是把整个uc/os 操作系统中止,还是只是中止uc/os 正
在执行的任务.不受管理的中断完成后,接着执行什么
A:可以发生,中断整个RTOS.
Q:我看了您在lpc210x 上的移植代码,你在说明中说:"如果您想通过软件仿真,请将
target.c 中的第 51 行屏蔽, 这样就可以看到任务逐个切换,最后将进入空闲任务."
我照这做了,但是在单步或者设断点执行时会产生异常,原因是未定义指令
OS_ENTER_CRITICAL()引起的,经过编译的函数都会变成蓝色,但这个函数还是黑色,因
为它实际上是一个软中断,请教您如何调试才能看到任务逐个切换 谢谢!
A:1.屏蔽的那一行是死等锁相环锁定,软件仿真时是没有锁相环的.
2.黑色是正常的,因为没有定义成函数.
3.因为你的 AXD -> OPTION -> 配置处理器中的 VECTOR CATCH 中的 S 选中了,所以 AXD
将你的软件中断当成了异常给捕