请教s3c2410-UART2以DMA方式进行数据读取的驱动中问题,感谢

发布于 2022-09-20 13:32:31 字数 1415 浏览 18 评论 0


请教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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

明明#如月 2022-09-27 13:32:31

kernel panic了,肯定是对内存非法操作了。我没有看你的代码,不过建议你检查一下你里面的dma映射等有关内存操作的部分。

意中人 2022-09-27 13:32:31

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一直发送数据,这一点确定)
(波特率也没问题。因为我用中断的方式成功地读取到了数据)

麻烦高手指点,感谢!(我又更新了一下的源码 见此贴附件)

梦在深巷 2022-09-27 13:32:31

我想LZ提几个问题:
1、你对这些程序真正的了解熟悉不?我看到你叙述说“似乎是……”,觉得你对程序的把握性还不够(个人推测,这是个题外话);
2、为什么要发生DMA3中断?你在哪里初始化这个中断了?明确它会在何时被触发么?要明白,申请成功了那只是一个中断号,并不代表能在你希望的时候产生中断;
3、kernel panic多数是在内存非法操作时产生,如果按你所说,你这里一直等待未产生的信号量,也顶多是个死锁问题,还不至于导致kernel panic。

悟红尘 2022-09-27 13:32:31

我本来在驱动里加了一个内核定时器,
每隔1s就打印下相关寄存器的状态。
加内核定时器的情况下,程序启动,每到130s左右的时候,就出现一楼的错误信息。

把这个内核定时器取消了后,就没有出现一楼的错误了。

檐上三寸雪 2022-09-27 13:32:31

我出现过类似问题,
查到最后是指针使用出错了!
建议楼主查一下中断中的指针!!

我不吻晚风 2022-09-27 13:32:31

原帖由 robotlee2002 于 2008-8-8 11:40 发表
我本来在驱动里加了一个内核定时器,
每隔1s就打印下相关寄存器的状态。
加内核定时器的情况下,程序启动,每到130s左右的时候,就出现一楼的错误信息。

把这个内核定时器取消了后,就没有出现一楼的错误了。

这是做成非法内存读取的原因
有些寄存器,它的内容是硬件自动更新的。当它被更新后,你想去读取它,但它已经不存在了

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文