内核定时器使用的错误

glacierful 2010-05-10 10:58:13
想使用内核定时器来对开发板上的灯,定时的点亮、关闭,相成闪烁的效果。在用户态应用程序调用这个驱动时,linux直接崩溃了,问题出在定时器调用的那个函数中:

void led_twinkle_timer_function(unsigned long arg)
{
if (!led_twinkle_status)
{
myled_ioctl_led_on();
//printk(KERN_ALERT"led on \n");
led_twinkle_status = 1;
}
else
{
myled_ioctl_led_off();
//printk(KERN_ALERT"led off \n");
led_twinkle_status = 0;
}

mod_timer(&myled_dev->s_timer, jiffies+HZ);
}

执行到myled_ioctl_led_on()或者myled_ioctl_led_off()时就出错了。奇怪的是如果把这两个函数禁掉,直接printk,是正常的。函数中就是调用了一个内核中的函数,而且不用时钟,直接调用时是正常的。

void myled_ioctl_led_on(void)
{
cpm2_set_pin(2, 13, CPM_PIN_OUTPUT|CPM_PIN_GPIO|CPM_PIN_VALUE_0);
}
...全文
373 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
glacierful 2010-05-11
  • 打赏
  • 举报
回复
我说一下出错的原因:
ioremap函数中调用了get_vm_area这个函数,而get_vm_area在分配内存空间时,使用的是kmalloc( , GFP_KERNEL)。kmalloc使用GFP_KERNEL分配内存时,可能会引起睡眠。
在内核定时器实际上也是用的时钟中断,在中断中是不允许休眠的,所以内核就崩溃了。
把ioremap移到驱动程序的初始化函数中就正常了。
pottichu 2010-05-11
  • 打赏
  • 举报
回复
ioremap在时钟中断的函数中不能这么使用吗?

ioremap 可能会引起休眠。。。

寒。 去看了一下那个帖子, 我居然也有回复。。
glacierful 2010-05-11
  • 打赏
  • 举报
回复
问题解决了。
从这儿得到的答案:http://linux.chinaunix.net/bbs/viewthread.php?tid=1132581
glacierful 2010-05-11
  • 打赏
  • 举报
回复
跟踪了一下程序到这一步就导致linux崩溃了:
cpm2_map_t __iomem *cpm2_immr = ioremap(0xF0000000, CPM_MAP_SIZE);
ioremap在时钟中断的函数中不能这么使用吗?
glacierful 2010-05-10
  • 打赏
  • 举报
回复
错误信息:
------------[ cut here ]------------
Kernel BUG at c005e6dc [verbose debug info unavailable]
Oops: Exception in kernel mode, sig: 5 [#1]
Freescale MPC8272 ADS
Modules linked in: myled
NIP: c005e6dc LR: c001313c CTR: 00000000
REGS: c0281cf0 TRAP: 0700 Not tainted (2.6.25)
MSR: 00029032 <EE,ME,IR,DR> CR: 28002024 XER: 20000000
TASK = c026a570[0] 'swapper' THREAD: c0280000
GPR00: 00000100 c0281da0 c026a570 00040000 00000001 c5000000 fcfb1000 ffffffff
GPR08: 000000d0 c0280000 00000000 f0000000 42002028 ffffbfef 03ffc000 00800000
GPR16: ffffffff 00000000 007fff00 001440cd ff810040 03baf0cd 03ff70ec 00000000
GPR24: c0270000 c0280000 00000001 fcfb1000 c5000000 00000020 00000000 00000015
Call Trace:
[c0281da0] [00002b72] (unreliable)
[c0281dc0] [c001313c]
[c0281df0] [c507528c]
[c0281e10] [c5075578]
[c0281e20] [c00269d8]
[c0281e60] [c0022c20]
[c0281e90] [c0006338]
[c0281ea0] [c0022ab0]
[c0281eb0] [c000d390]
[c0281ed0] [c0010480]
--- Exception: 901[c0281f90] [c0008f20] (unreliable)
[c0281fb0] [c01ef050]
[c0281fc0] [c0246950]
[c0281ff0] [00003438]
Instruction dump:
901e0014 4bffff70 9421ffe0 7c0802a6 bf410008 54290024 7c9a2378 90010024
7cbc2b78 7cdb3378 8009000c 5400012e <0f000000> 70800001 3be00001 3bc0ffff
Kernel panic - not syncing: Fatal exception in interrupt
Rebooting in 180 seconds..
pottichu 2010-05-10
  • 打赏
  • 举报
回复
我也遇到过定时器引起kernel 崩溃的问题, 没找到原因,关注一下,呵呵。
atiansk2006 2010-05-10
  • 打赏
  • 举报
回复
有错误信息吗?
glacierful 2010-05-10
  • 打赏
  • 举报
回复
cpm2_set_pin(2, 13, CPM_PIN_OUTPUT|CPM_PIN_GPIO|CPM_PIN_VALUE_0);
这个是访问管脚的寄存器的,是不是需要用自旋锁保护才行?
Kyph 2010-05-10
  • 打赏
  • 举报
回复
在内核定时器的上下文中,代码会受到许多限制。定时器函数必须原子地运行:
1)不允许访问用户空间
2)不能访问current指针
3)不能执行休眠或这调度,schedule或者wait_event,或者kmalloc等等。

4,436

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧