请教s3c2410-UART2以DMA方式进行数据读取的驱动中问题,感谢
请教s3c2410-UART2以DMA方式进行数据读取的驱动中问题,感谢
我的目标平台为 s3c2410 - linux2.4.18
宿主机开发开发平台为:redhat9.0
做对UART2以DMA方式进行数据读取的驱动
(UART2的读采用DMA,写不采用DMA)
目前程序基本写完,但存在一些问题。
我在驱动程序的read里 down_interruptible(&b->sem),
b为DMA驱动里的缓冲区数据结构实例
等待驱动的DMA中断中释放信号量(驱动里up(&b->sem);)。
我的程序在等待获取信号量时,出现如下错误:
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
*pgd = 00000000, *pmd = 00000000
Internal error: Oops: 0
CPU: 0
...
...
...
Code: bad PC value.
Kernel panic: Aiee, killing interrupt handler!
In interrupt handler - not syncing
附件中为驱动程序源码:
uart_driver.c 为驱动程序
uart_test.c 为驱动测试应用程序
麻烦熟悉或做过此类开发的朋友为我看看,感谢。
我只有5个积分,所以只能给您5个积分。
。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
kernel panic了,肯定是对内存非法操作了。我没有看你的代码,不过建议你检查一下你里面的dma映射等有关内存操作的部分。
UART2的设置,我在 uart_init_port()里完成了。
local_irq_save(flags);
GPHCON = (GPHCON&0xff00ff)|0x00aa00;
GPHUP = 0x7ff; // The pull up function is disabled GPH[10:0]
UART_ULCON2 = 0x03;
UART_UCON2 = (UART_UCON2 & 0xff0) | 0x006 | IS_LOOPBACK;
UART_UFCON2 = 0x30; // 0011 0000 bit0先不使能
UART_UBRDIV2 = 26; // 初始波特率为 115200 */
local_irq_restore(flags);
针对UART2的DMA的设置,似乎是在dma.c中完成。(dma.c为开发板上系统中提供的源码)
(因为我没有对DMA寄存器进行配置,但调用dma.c里的函数后,那些寄存器都设置好了。)
(不过也比较奇怪,在dma.c中的 dma_irq_handler()里,连清中断标志与清未决寄存器都没有看见。)
在驱动程序初始化init中,调用了dma.c中的。
s3c2410_request_dma( "UART2", s->dma_ch, NULL, uart_dma_in_callback );
并且在这个函数里request_irq()申请了中断号INT_DMA3(为20),并且申请成功了。
而后,针对UART2的DMA的寄存器在s3c2410_request_dma()后为:有输出信息:
uart_read(407): DISRCC3 = 0x 3
uart_read(40: DIDSTC3 = 0x 0
uart_read(409): DCON3 = 0x a0c00400
uart_read(410): DSTAT3 = 0x 0
uart_read(411): DMTRIG3 = 0x 2
uart_read(412): DISRC3 = 0x 50008024
uart_read(413): DIDST3 = 0x 33a94000
uart_read(414): DCDST3 = 0x 0
uart_read(415): DCSRC3 = 0x 0
uart_read(416): UCON2 = 0x 6
uart_read(417): UFCON2 = 0x 31
uart_read(41: SRCPND = 0x 0
uart_read(419): INTPND = 0x 0
uart_read(420): INTMSK = 0x a3e3bffb
里面DMA相关的寄存器都配置好了,
(源地址设置好了,即UART_URXH2)
(目的地址也设置好了,我看是DMA环形缓冲区第一个buf的物理首地址)
(DISRCC3 与DIDSTC3 也设置对了。)
(在dma.c中的函数里设置的,我没有管)
中断相关寄存器我也没有管。(发现自己对INTMSK ,INTMOD,SUBSRCPND设置了,结果也一样)
在dma.c中将INTMSK 也设置对了,其bit20即DMA3的屏蔽位设为0了,允许中断
随后就对DMA的缓冲区(申请了3个)进行了申请。
接着将申请的缓冲区加入了DMA的环形缓冲队列。s3c2410_dma_queue_buffer();
随后,程序就一直在read的down_interruptible(&b->sem)里等待DMA3中断里释放信号量。
每次都是经过140s左右的样子,就出现 我的一楼帖子 的错误。
我觉得是不是linux发现read中在等待信号量的释放,而这个信号量一直没有释放,
一段时间以后,就会:
Kernel panic: Aiee, killing interrupt handler!
In interrupt handler - not syncing
为什么就没有DMA3的中断呢?我还漏掉了什么?DMA与UART2寄存器我感觉都设置好了。
(我通过另一个板子向跑此程序的试验箱上的UART2一直发送数据,这一点确定)
(波特率也没问题。因为我用中断的方式成功地读取到了数据)
麻烦高手指点,感谢!(我又更新了一下的源码 见此贴附件)
我想LZ提几个问题:
1、你对这些程序真正的了解熟悉不?我看到你叙述说“似乎是……”,觉得你对程序的把握性还不够(个人推测,这是个题外话);
2、为什么要发生DMA3中断?你在哪里初始化这个中断了?明确它会在何时被触发么?要明白,申请成功了那只是一个中断号,并不代表能在你希望的时候产生中断;
3、kernel panic多数是在内存非法操作时产生,如果按你所说,你这里一直等待未产生的信号量,也顶多是个死锁问题,还不至于导致kernel panic。
我本来在驱动里加了一个内核定时器,
每隔1s就打印下相关寄存器的状态。
加内核定时器的情况下,程序启动,每到130s左右的时候,就出现一楼的错误信息。
把这个内核定时器取消了后,就没有出现一楼的错误了。
我出现过类似问题,
查到最后是指针使用出错了!
建议楼主查一下中断中的指针!!
这是做成非法内存读取的原因
有些寄存器,它的内容是硬件自动更新的。当它被更新后,你想去读取它,但它已经不存在了