Chinaunix首页 | 论坛 | 博客
  • 博客访问: 481555
  • 博文数量: 51
  • 博客积分: 1056
  • 博客等级: 少尉
  • 技术积分: 676
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-10 22:53
文章存档

2018年(2)

2017年(1)

2013年(2)

2012年(9)

2011年(36)

2010年(1)

分类: LINUX

2011-04-14 17:28:41

折腾了我两天的一个问题,自己写一个wm8350-adc驱动,老是报
BUG: scheduling while atomic:xxxxxxxxxxxx

终于知道这种信息是说在中断中产生了睡眠。我没有在硬中断中使用读取adc寄存器的值,但是在内核定时器里也是不行的。内核定时器处理函数属于软中断上下文,无论软中断还是硬中断,都不允许睡眠。最后改用中断线程做的,代码似乎比内核定时器还少。以下是一个简单模型,使用内核线程周期地执行一个动作

  1. 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;
               
               

  2.              do_someting();

  3.             //每隔1s执行1次,然后睡眠,可被信号提前唤醒

  4.              schedule_timeout_interruptible(1*HZ);
             }

        set_current_state(TASK_RUNNING);
        return 0;
    }



  5. //注册内核线程
  6. 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) |
给主人留下些什么吧!~~