Zynq cap调试总结

来源:互联网 发布:淘宝怎么卖家充话费 编辑:程序博客网 时间:2024/05/21 06:01

遇到的问题和解决方法

1、ramdisk启动之后,必须先ls一下,才能open文件。

问题定位方法:gdb,显示栈。

问题定位:open函数会调用到内核中的kunmap函数,而kumap函数不能在中断上下文中调用(在kunmap函数中有BUG_ON( in_interrupt ( )) ;) ,而我们 f ilp_open正是在中断上下文中调用的,因此出错。

解决方法:启动内核线程,来open文件。

2、结构体的地址被莫名其妙地修改了。

问题定位方法:打印

问题定位:结构体的地址保存在一个局部变量中(在内核栈) ,当在内核中定义个大的局部变量时,就有可能把内核栈堆满,从而冲掉到栈上其它变量。

解决方法:将数组换成指针。

总结:内核栈有限,不要过分的去用,这是常识。

3、内核死在 synchronize_irq函数中。

问题定位方法:gdb,打印栈。

问题定位:synchronize_irq会被disalbe_irq调用,通常情况下会在驱动注册的中断处理函数中调用 disalbe_irq来使中断处理能嵌套。问题出在,在synchronize_irq中会判断

IRQD_IRQ_INPROGRESS标志,而IRQD_IRQ_INPROGRESS会在调用驱动注册的中断处理函数之前的中断处理流程中(handle_irq_event函数中)设置,因此造成死锁。

解决方法:把 disalbe_irq换成disable_irq_nosync。

总结:以后还是使用disable_irq_nosync比较靠谱。

4、timer中断

问题描述:想在内核中写一个 timer的驱动,中断通过setup_irq来建立,一打开 timer的中断,内核就死掉。

问题定位:代码逻辑上捋中断处理流程,发现在zynq平台,这个timer的中断处理和普通的 驱 动 中 断 处 理 不 相 同 。 其 中 断 处 理 必 须 在 arch/arm/include/asm/entry-macro-multi.S中加入,不能使用setup_irq函数来建立。当然不要忘记在init函数中,使能中断。

问题解决:在 arch/arm/include/asm/entry-macro-multi.S加入如下代码:

36 ____test_for_gt irq r0, r6, r5, lr

37 ____movne___r0, sp

38 ____adrne___lr, BSYM(1b)

39 ____bne_internal_t imer2_int

其中 test _for_gt irq为:

76 ____.macro test _for_gt irq, irqnr, irqstat, base, tmp

77 ____bic_\irqnr, \irqstat , #0x1c00

78 ____mov ____\tmp, #0

79 ____cmp_\irqnr, #27

80 ____moveq___\tmp, #1

81 ____streq___\irqstat , [\base, #GIC_CPU_EOI]

82 ____cmp_\tmp, #0

5、记住一点,现在的串口驱动都是使用的定时器轮寻收发数据,而非中断方式。

6、内核不能挂载文件系统

问题定位:内核启动到挂载文件系统之后就会死掉,通过实验发现可能是内核image过大加载时冲掉了ramdisk的空间,但是就是比平常的image大2M应该也没什么影响,后来查看System.map,发现虽然image的大小变化不大,但是一些变量的地址却变化很大,用到了ramdisk的空间。

解决方法:在uboot中讲ramdisk的起始地址后移。

原创粉丝点击