硬件平台:英飞凌 OKA40i 开发板
软件平台:VxWorks 6.6
最小系统所需要的驱动包括:
汇编启动文件, mmu 配置 串口, ARM 内核通用定时器, GIC
bug0: 串口打印字符串为错误值,经过测试,函数调用时参数传递错误。
解决:这是因为我之前设置的 tftp 下载地址为 0x41000000, 而 RAM_LOW_ADRS 宏的值为 0x41100000, 空间只有 1M,不足以装载整个操作 elf 系统镜像,当 uboot 拷贝 elf 是会破坏原 elf 文件,将 tftp 下载地址更改为 0x40b00000, 问题解决 是地址空间溢出导致的
bug1: VxWorks 启动后可以进入 usrInit(),但无法进入 usrRoot()
进入 kernelInit() 之后就再也没有输出了,而且这个函数,尼玛是不开源的,调都没法调试,cnm
测试1:在启动文件中,将中断打开,有概率(wcnm)可以进入 usrRoot(). 那么为什么呢?为什么会是概率进入呢???关闭就稳定进不去 usrRoot()?
测试2:我在 usrInit() 失能 GIC,可以稳定进入 usrRoot(); cnm,什么毛病, 不过果然是中断的问题
解决:在启动文件 sysALib.s 中,直接失能 GIC,问题解决,可以进入 usrRoot(). 所以应该是 uboot 配置了 gic, 在 uerKernelInit() 中重新使能中断时导致了系统跑死
bug2: 在执行完系统时钟初始化后,系统跑死。
经过测试,只要不使能时钟中断,就不会死,一使能时钟中断,就会死
那么猜测,是中断的问题,中断向量表的问题?我感觉是寻址跑飞。
测试1:打印一下中断向量表:
VxWorks 的中断向量表基地址为 0,并没有通过设置 VBAR 寄存器重映射中断向量表基地址,所以BSP 开发过程中,我们应该把 0 地址重映射到系统 RAM 地址起始处
Vectors: address 0x00 = 0xe7fddefe address 0x04 = 0xe59ff0f4 address 0x08 = 0xe59ff0f4 address 0x0c = 0xe59ff0f4 address 0x10 = 0xe59ff0f4 address 0x14 = 0x53c540af address 0x18 = 0xe59ff0f4 address 0x1c = 0xdd9d9774
没有问题,0x18 为 IRQ 向量,存储的是一个跳转指令 0xe59ff000,跳转到 0xf4?
查看代码发现,VxWorks 系统内真正的向量表基地址为 0x100
向量表如下:
address 0x100 = 0x4115858c address 0x104 = 0x411582cc address 0x108 = 0x4115857c address 0x10c = 0x411582f8 address 0x110 = 0xffffffff address 0x114 = 0x4114a678 address 0x118 = 0xfff7ffff address 0x11c = 0xffffbfff
中断向量表配置是正确的
测试2:查看是否触发中断
经过测试,系统一直在触发系统定时器中断,所以死了。
难道是时间间隔设置错了?
并不是,我在时钟中断处理函数中将重新使能定时器的接口关了,依然会有这个现象,这应该是系统与 bsp 的中断接口编写的有问题造成的。
更改适配的中断系统接口,问题依旧存在。在中断服务程序中失能对应中断,则不会一直触发中断。
测试3: 读取定时器频率
经过测试,发现定时器频率读出来是 0. 难怪一直触发 Timer 中断
**解决(暂时):**那么手动设置定时器频率为 24M。所以不是 gic 驱动的问题,妈的
待解决 bug: ARM 通用定时器频率读出来为 0
也许需要手动设置频率?
解决: 参考 《ARM 架构手册》B8.1.1 节内容,得知,需要手动设置 ARM 通用定时器的频率为 1-50 MHz。 所以是没有设置通用定时器频率造成的
bug3: 系统一直触发串口中断
是因为我在串口中直接操作 THR 发送打印,而此时串口的发送中断标志位已经被清除,当打印信息发送完成,又会触发发送中断,(PS:串口发送中断一直开着,也许应该优化驱动?)
解决: 不要调用 bspDbgMsg(), 该函数会直接写串口发送寄存器,即删除串口中断中的打印代码
bug4: usrRoot() 运行过程中触发未定义指令异常
系统打印如下:
Undefined instruction Exception address: 0x4114d9d0 Current Processor Status Register: 0x60000113 Task: 0x4ceef6d8 “tRootTask” 0x4ceef6d8 (tRootTask): task 0x4ceef6d8 has had a failure and has been stopped. 0x4ceef6d8 (tRootTask): fatal exception in a kernel task or stack overflow !
将 usrRoot() 函数中对 C++ 的支持注释掉,可以规避该问题。
代码死在如下函数中:
cplusCtorsLink(); //这什么函数, 注释说是编译生成的?
解决: 反正也用不到 C++,直接注释掉。
|