VxWorks笔记
利用vxWorks可裁减可动态链接特性进行模块调试的分析
a) 首先,可将root.c简化,去掉大部分不需要加载的模块和想要调试的模块,以加快系统启动速度。
b) 如果vxworks加载的.o中引用了目前系统中不存在的symbol,则系统将该symbol的指针置为0,
即使后面加入了定义该symbol的.o文件,也不会将前面的引用修正,执行这些函数时,系统会崩溃。
因此不能分开加载互相依靠的.o文件。而vxWorks又不能加载.a文件(由于不是elf格式)。
解决方法是:将这些.o文件链接成可执行的.out文件,或用ld -o命令将这些.o文件生成一个大的.o文件再加载,
如:ld -o -r garp.oo garp.o garp_cmd.o gid.o gidtt.o gip.o sys.o
其中-r表示产生可重定位的输出, 比如,产生一个输出文件它可再次作为’ld’的输入.这经常被叫做"部分连接".
c) 加载方法:在shell中执行ld < garp.oo或ld 1, 0, “garp.oo” ,
其中后者将内部连接的符号(如静态函数)也加入系统符号表中,这样就可以直接在shell中调用静态函数了。
使用moduleShow命令可以查看目前已加载的模块。
d) 加载后在shell中执行模块初始化函数,如garp_init 。
如果运行效果不理想,可重新编译该模块并重新加载。
e) 因为garp等模块初始化时,分配了许多系统资源,因此在重新加载前,需要对其进行销毁。
可编写诸如 garp_cleanup 等函数,专门用于调试时释放资源。
在shell中执行garp_cleanup函数,然后卸载:unld “garp.oo” 。
f) 重新加载后,再执行garp_init。
g) 由于
interface_set_showrunning_service,
registercmd,registerncmd,
register_subcmd,
register_module_version
等注册函数所在模块未提供相应的反注册函数,注册多次系统会出问题,因此要保证其只注册一次。
可将garp_init中涉及到这些函数的调用语句注释掉,在第一次加载时手工调用,
以后只要操作系统不重新启动,重新加载不要再调用这些函数。
h) 在操作系统启动后,立刻进行所有端口的创建和状态通知,因此我们加载的模块得不到这些通知。
可手工调用相关的回调及其下层函数,进行“假通知”,
如果需要调用静态函数,最好以ld 1,0,”garp.oo”方式进行加载。
函数调用栈结构
Last sp
PC
……
Last2 sp
PC
……
Last3 sp
PC
……
使用SYS_PC_SAVE宏,可以得到指针sp,指向Last sp。而last sp单元中存储的值则是指向last2 sp的指针,依此类推。
PC中存储的是该段代码的调用地址。
如下代码可以打印出某行代码的调用关系(打印1至2级调用者)
SYS_PC_SAVE
Print("[%s:%d:%s] is called at 0x%08x from 0x%08x\n",
__FILE__, __LINE__, __FUNCTION__,
SYS_PC_GET, *(uint32*)(*((uint32*)(&SYS_PC_GET)-1)+4)
);
SYS_PC_RESTORE
注:
#define SYS_PC_SAVE register uint32* sp asm(“1”);{
#define SYS_PC_RESTORE }
#define SYS_PC_GET ((uint32)(*sp + 4))
变量初始化
是填成全"E" (0x1110),而不是全0
字节序
字节序和处理器有关,小字节序就是高位字节存储于内存的高位地址,低字节存储于内存的低位地址处,甚至连比特位都是如此。大字节序正好相反。基于intel处理器的PC使用的是小字节序(LITTLE ENDIAN),嵌入式处理器多使用大字节序。
LR与堆栈
LR与IP处于同一个函数的情况:f1()调用f2()时,将LR置为f1()中调用f2()之后的那条指令,从f2()返回f1()后,则LR与IP都处在f1()中。注意:这种情况肯定发生在有子函数调用的函数,发生异常时IP>LR。
f1()调用f2()时,如果f2()中还会调用其他函数f3(),则编译器会在f2()入口生成代码将LR(f1()中调用f2()之后的指令地址)写入f1()的堆栈,如果f2()不调用任何函数,则不会生成相应代码。
Vx的几大优势和特点
1、可裁减的微内核结构
2、微内核系统的内存管理运行在用户态,而非内核态,低优先级任务在内存分配过程中可被高优先级任务抢占,不会影响实时性。
3、内核无对应的任务和上下文。
4、每个任务的上下文中都保存切出前的errno值并在切入时恢复,相当于每个任务有一个独立的errno变量。
5、为快速响应中断,ISR运行在特定的空间,不同于其他任何任务,因此中断处理没有任务的上下文切换。
6、实时系统的设计目的不是追求大吞吐量,而是响应的及时性。我们希望系统始终以50微秒的延时处理一个事件,而不是有时20微秒有时100微秒。
process / thread / task
在很多场合两者概念可互换,process多见于桌面操作系统,每个进程间有内存保护;
而task多见于嵌入式系统,task间无内存保护,可操作同一块全局存储区,这在进程间是不可能的,进程间可通过消息队列来通信。
thread可称为轻量进程,同一进程内的不同线程,可以共享该进程内的同一存储区。
在嵌入式系统中,可以认为各任务就是运行在系统唯一一个进程中的不同线程。
大多数嵌入式系统都采用基于优先级抢占的任务调度方式。juniper的系统采用的是不可抢占的方式。
驱动接收报文有两种方式:
poll(询问):相对低效,定期查询设备有没有报文收到。
ISR(中断服务程序):高效,但是每收到报文都有中断产生,流量大时,容易造成系统过载。
驱动发送报文时,需要在发送完成后,释放buffer。发送完成通知方式也是poll和ISR两种。
一般发送成功由poll通知,发送出错由ISR通知,driver需要对设备进行reset。
shell
tornado shell中,
?shConfig SH_GET_TASK_IO off
可以将printf输出到目标机
?shConfig SH_GET_TASK_IO on
输出到windshell本身
vxWorks中对时间的精确统计
原始资料来源:http://topic.csdn.net/u/20070703/12/d94a3121-4272-4715-9de4-d39e201f6f56.html
我查了一下,好多网友也给出了不少关于获得毫秒级时间的方法和建议,粘贴如下,
供大家参考:
帖1:
如果支持Timestamp,BSP应提供以下函数
sysTimestampConnect() - 连接时间戳中断
sysTimestampEnable() - 使能时间戳
sysTimestampDisable() - 禁止时间戳
sysTimestampFreq() - 取得时间戳的频率
sysTimestampPeriod() - 取得时间戳周期
sysTimestamp() - 取得时间戳
sysTimestampLock() - 禁止中断,取得时间戳
sysTimestampInt() - 可选的时间戳ISR
帖2:
时间戳就是一个高精度的时钟吧?由于精度高,记录时间的这个变量变化的很快,所以他很快就会溢出,重新从0开始计数,我有时候用它来计算某个函数的运行时间。
time1,time2,freq;
freq=systimestampFreq();
time1=sysTimestamp();
myFunc();
time2=sysTimestamp();
(time2-time1)/freq大概就是时间了。
但是,这有一个条件,就是myFunc()运行的很快,用tickGet()难以计算的情况。否则,可能当time2获取值的时候,时间戳都已经溢出了好几次了。
就算是这样,也不定就成功,可能当得到time1的时候,变量已经要溢出,等得到time2的时候,得到是是一个很小的值,结果,time2-time1就是负值了。
总之,利用它,在某些情况下,还是可以做一些估算的。
帖3:
vxWorks下的tick和timestamp没有什么相关性。也不是你说的秒和分的关系。
tick 其实可以看成内核调度的频率,也是是时间片、watchdog超时、任务延时的单位,所以是system clock。timestamp能够得到高精度的计时,跟RTOS调度没什么关系。比如在某个时候读寄存器的计数为A,过一段时间后再读为B,主频为f。 那么B和A之间的时间距离就是:T = (B-A)*f。(假设用做timestamp的timer没有rollover)对应到硬件上,tick只要timer能够产生periodic中断就 行,用做timestamp的timer要求多一点点。
贴4
要获取精确的毫秒的时间间隔,而且频繁的调用又不导致系统CPU占用率过高。
我建议采取 通过 CPU 机器周期的方法解决。
基本上大部分主流CPU都一个64位寄存器用来记录CPU上电后的 机器周期个数。
你可以编写一个汇编函数获取这个 64位计数。
然后你在程序开工时,作一个10秒的定时,在定时前后各获取一次CPU 机器周期。
然后相减,就可以得到每秒钟的CPU 机器周期,
这个数字除以1000就是每毫秒的CPU 机器周期。
这个值可以在运行中作为常量,使用我们将之命名位 毫秒因子
然后你在上一个次执行时取一下上一个次执行和下一次执行,
下一次执行时再取一次上一个次执行和下一次执行。
两次相减得到 间隔的CPU 机器周期 。然后利用上面毫秒因子换算成毫秒就可以了。、
利用这种方法你就是想精确到 纳秒 也是可以的。
我们经常用这个方法来测量 一段代码的准确执行时间。
VxWorks 任务调度
Vx有没有空任务?
原贴地址:http://topic.csdn.net/u/20070207/16/8da9259a-65b8-4856-8e48-761ad1dd00fa.html
搂主有条件可以看看 vxworks 的内核代码
分析reschedule 函数你可以看到
在这个里面有一个while死循环,读ready队列
如果ready队列为空,就在这里一直while死循环的读ready队列
所以空跑Vxworks的话,是没有IDLE任务
— 这跟多任务分时系统WIN32 LINUX是不一样的,这种操作系统boot以后有个init任务,会起idle任务
在linux内核代码中你可以看到的:)
但是由于使用Vxworks的大多都填了root函数,Vxworks启动后根据配置文件会调用这个函数
这个root函数里面,大多数人的处理都是起了一个优先级255的for死循环
所以,在加入root后的Vxworks(这个就不是仅仅只有一个Vxworks的kernel了)是有一个idle任务
永久性的在ready队列里面
导致reschedule里面的while总是可以读到一个ready态的任务
还有什么不明白的,建议看代码,如果看不到,欢迎交流
VxWorks笔记的更多相关文章
- VxWorks 6.9 内核编程指导之读书笔记 -- POSIX
POSIX能力 VxWorks扩展了POSIX,为了移植,VxWorks提供了额外的POSIX接口作为可选组件.VxWorks实现了POSIX 1003.1(POSIX .1)一些传统接口以及POSI ...
- VxWorks 6.9 内核编程指导之读书笔记 -- ISRs和Watchdog Timer
中断服务程序 ISR 硬件中断处理是实时系统的关键,因为它是外部时间通知系统的方式. ISR亦称为中断处理函数,是对中断的正确响应.可以使用任何ISR连接到任何没有被VxWorks使用的中断上.当关联 ...
- VxWorks 6.9 内核编程指导之读书笔记 -- Singnals
Signals 信号是操作系统用于异常处理和异步控制流的关键.在很多方面,信号相当于软件方面的硬件中的中断.操作系统产生的信号包括总线错误和浮点处理异常.信号也提供了API来管理和产生信号.在应用程序 ...
- VxWorks 6.9 内核编程指导之读书笔记 -- 多任务
概述 VxWork系统任务 任务调度 任务创建和管理 任务的错误状态 任务异常处理 共享代码和重入 概述 现代实时操作系统是基于多任务和任务间通信的概念的.多任务环境运行一个实时进程RTP可以被作为一 ...
- VxWorks 6.9 内核编程指导之读书笔记 -- 多任务(二)
VxWorks的系统任务 VxWorks在引导时启动的系统任务依赖于配置,有些总是运行.任务集与VxWorks的基本配置相关,很少的任务常用于可选的组件. 注意:别挂起.删除或改变任何系统任务的优先级 ...
- VxWorks 6.9 内核编程指导之读书笔记 -- C++开发
5.1 介绍 针对C++的VxWorks配置 C++头文件 使用C++启动任务 C和C++之前调用代码 C++编译器说明 在信号处理和ISR中使用C++ 下载C++编写的内核模块 C++编译器的不同 ...
- VxWorks 6.9 内核编程指导之读书笔记 -- VxWorks Kernel application (二)
#1 内核对象的静态实例化 内核对象的静态实例化 任务的静态实例化 VX_TASK宏用来在编译时声明一个任务对象.该宏带有2个参数:任务名和栈大小.不像taskSpawn函数,任务名称可以是NULL. ...
- VxWorks 6.9 内核编程指导之读书笔记 -- VxWorks kernel application (一)
#1 什么是内核应用程序? #2 开发内核应用程序注意事项 什么是内核应用程序? 内核应用程序不同于RTP程序,它允许在内核态,与操作系统使用相同的地址空间.因此,它与操作系统会相互干扰.它可以编译成 ...
- VxWorks 6.9 内核编程指导之读书笔记 -- VxWorks Small-Footprint Configuration
什么是Small-footprint? Small-footprint常见关键配置? 如何配置Small-footprint? 什么是Small-footprint? Small-footprint配 ...
随机推荐
- [Linux]Linux下Apache服务器配置
Linux下Apache服务器配置 相关包: httpd-2.2.3-29.e15.i386.rpm //主程序包 httpd-devel-2.2.3-29.e15.i ...
- VSTO:使用C#开发Excel、Word【6】
Office主互操作程序集(PIA)在了解如何构建Office解决方案之前,您需要更详细地了解在.NET中与Office对象模型通信的托管程序集.用于与Office通话的托管程序集称为Office主互 ...
- 3-D models provided some resources
http://d-earth.jamstec.go.jp/GAP_P4/ http://ds.iris.edu/ds/products/emc-earthmodels/
- matlab运行中出现“Caught "std::exception" Exception message is: Message Catalog MATLAB:builtins was not loaded from the file."
在我运行过程中,经常爆出这一不确定是什么的问题,经排查后发现,原来是fopen 文件后,没有及时fclose导致的.
- <YARN><MRv2><Spark on YARN>
MRv1 VS MRv2 MRv1: - JobTracker: 资源管理 & 作业控制- 每个作业由一个JobInProgress控制,每个任务由一个TaskInProgress控制.由于每 ...
- day 74 json 和 ajax 的实例
一 json的定义: json(JavaScript object notation,js对象标记)是一种轻量级的数据交换格式,它基于ecmascript(w3c指定的js规范)的一个子集,采用完全独 ...
- 【转】strmbasd.lib(dllentry.obj) : error LNK2001: 无法解析的外部符号"int g_cTemplates"
加入了DirectShow的基类链接库后,如果此时编译就会出现以下编译错误: strmbasd.lib(wxutil.obj) : error LNK2019: 无法解析的外部符号 __imp__ti ...
- MFC 关于new出一个新对话框时,退出对话框内存泄漏的问题解决
问题: 在进行点击按钮弹出对话框时,我是用了new来生成一个新的对话框,但是在新对话框关闭的时候,经过检查发现,新对话框存在内存泄漏问题. 原因: 因为使用了new,但是当时没有找到地方进行delet ...
- Python 多个装饰器装饰同一个函数
def wrapper1(fn): def inner(*args, **kwargs): print("1111111") ret = fn(*args, **kwargs) p ...
- POJ 3461 Oulipo(KMP裸题)
Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, without t ...