折腾了我两天的一个问题,自己写一个wm8350-adc驱动,老是报
BUG: scheduling while atomic:xxxxxxxxxxxx
终于知道这种信息是说在中断中产生了睡眠。我没有在硬中断中使用读取adc寄存器的值,但是在内核定时器里也是不行的。内核定时器处理函数属于软中断上下文,无论软中断还是硬中断,都不允许睡眠。最后改用中断线程做的,代码似乎比内核定时器还少。以下是一个简单模型,使用内核线程周期地执行一个动作
-
int ls_thread_func(void * argc)
{
//设置进程名
daemonize("ls_thread");
//允许信号SIGKILL
allow_signal(SIGKILL);
while(1)
{
set_current_state(TASK_INTERRUPTIBLE);
//如果收到信号(SIGKILL),就退出
if(signal_pending(current)) break;
-
do_someting();
-
-
//每隔1s执行1次,然后睡眠,可被信号提前唤醒
schedule_timeout_interruptible(1*HZ);
}
set_current_state(TASK_RUNNING);
return 0;
}
-
-
-
//注册内核线程
-
ret=kernel_thread(ls_thread_func, NULL,CLONE_KERNEL);
一般的adc像是s3c6410那种直接集成在soc里,通过memory映射IO内存,之后直接读写寄存器的,一般不会睡眠。wm8350同主处理器的接口是i2c,读写个寄存器都要经过i2c_master_send、i2c_master_recv,自然要注意睡眠问题。
关于内核同步和调度问题,还是lkd2讲得浅显易懂,lkd3目前只有英文版,还是弄来看看吧。
阅读(2118) | 评论(0) | 转发(1) |