当前位置:  技术问答>linux和unix

struct sys_timer 使用clock_event_device 机制该如何写?

    来源: 互联网  发布时间:2016-12-09

    本文导语:  在系统时钟时,中断能正常运行,能打印出".",能挂上文件系统,但是多线程程序在调度时候就挂掉了,请大家帮我看看这个模块是哪里出了问题,谢谢! #include  #include  #include  #include  #include  #include  #include  #...

在系统时钟时,中断能正常运行,能打印出".",能挂上文件系统,但是多线程程序在调度时候就挂掉了,请大家帮我看看这个模块是哪里出了问题,谢谢!


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 


/********************************************************************************
TIMER 寄存器地址
*******************************************************************************/
#define CTRL        (0x00 >> 2)
#define COUNT       (0x04 >> 2)

static volatile u32 *timer  = (volatile u32 *)ZX_IO_VA(TIMER1);


static struct clocksource           clk_source;
static struct clock_event_device    clk_event;


static cycle_t read_cycles(void)
{
    /*
    * 此处返回的是下一次中断还需要返回的tick数
    * 是否需要返回运行的tick数?
    * 存疑
    */

    //return ((CLOCK_TICK_RATE / HZ) - timer[COUNT]);
    return timer[COUNT];
}


static irqreturn_t timer_interrupt(int irq, void *dev_id)
{
//这个中断处理函数能正常进入
    //大家帮我看看这里是否有问题
    //在多进程程序中,多进程不能正常调度
    clk_event.event_handler(&clk_event);

    return IRQ_HANDLED;
}



static struct irqaction timer_irq =
{
    .name       = "timer1",
    .flags      = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
    .handler    = timer_interrupt,
};



/*******************************************************************************
* 函数名称: hw_timer_init
* 功能描述: 设置定时器 TIMER1 参数,使之每 1/HZ秒发生一个中断
* 输入参数:
* 输出参数:
* 返回值  :
* 说明    : 初始化控制寄存器
            0 0 1 0 0 0 1 0
            ------- -------- - -
               |              |  +- 停止计时器工作
               |              +- 产生中断后重载计数初值计数
            +- 外部时钟的分频因子,分频系数为2^(n+1)

* 修改日期  版本    修改人      修改内容
*------------------------------------------------------------
*09-06-25   1.0     WengYunFeng 新增
*******************************************************************************/
static void __init hw_timer_init(void)
{
    timer[CTRL]     = 0x2;                      //停止计时器,并进行初始化
    timer[COUNT]    = CLOCK_TICK_RATE / HZ;     //初始化计数
    timer[CTRL]     = 0x3;                      //打开计时器
}




static int set_next_event(unsigned long evt, struct clock_event_device *d)
{
    u32 v           = timer[COUNT] + evt;
    timer[COUNT]    = v  > 0xFFFF ? 0xFFFF : v;
    return 0;
}



static void set_mode(enum clock_event_mode m, struct clock_event_device *e)
{
    switch(m)
    {
        case CLOCK_EVT_MODE_PERIODIC:           //周期时钟
            timer[CTRL]     =   0x3;            //开始工作
            break;
        case CLOCK_EVT_MODE_ONESHOT:
            timer[CTRL]     =   0x2;            //停止
            timer[CTRL]     =   0x1;            //单发计数
            break;
        case CLOCK_EVT_MODE_UNUSED:
            timer[CTRL]     =   0x0;            //停止
            break;
        case CLOCK_EVT_MODE_SHUTDOWN:
            timer[CTRL]     =   0x0;            //停止
            break;
        case CLOCK_EVT_MODE_RESUME:
            timer[CTRL]     |=  0x01;           //工作
            break;
        default:
            break;
    }

}



static struct clocksource clk_source =
{
    .name       = "timer1",
    .rating     = HZ,                           /* 时钟定义来自HZ */
    .read       = read_cycles,              /* 返回定时器的cycle值 */
    .mask       = CLOCKSOURCE_MASK(16),         /* 是16Bit?*/
    .shift      = 24,
    .flags      = CLOCK_SOURCE_IS_CONTINUOUS,
};




static struct clock_event_device clk_event =
{
    .name           = "timer1_evt",
    .features       = CLOCK_EVT_FEAT_PERIODIC,// | CLOCK_EVT_FEAT_ONESHOT,
    .shift          = 24,
    .rating         = HZ,
    .set_next_event = set_next_event,
    .set_mode       = set_mode,
};




static void __init timer_init(void)
{
    /* 初始化硬件 */
    hw_timer_init();

    /* 初始化时钟源 */
    clk_source.mult         = clocksource_hz2mult(CLOCK_TICK_RATE, clk_source.shift);
    if(clocksource_register(&clk_source))
    {
        printk(KERN_ERR "CLOCK: clock source register failedn");
    }

    /* 初始化时钟事件 */
    clk_event.mult          = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,  clk_event.shift);
    clk_event.max_delta_ns  = clockevent_delta2ns(0xFF00, &clk_event);
    clk_event.min_delta_ns  = clockevent_delta2ns(0x0010, &clk_event);
    clk_event.cpumask       = cpumask_of_cpu(0);

    clockevents_register_device(&clk_event);

    /* 设置定时器中断 */
    setup_irq(INT_NUM_TIMER1, &timer_irq);
}



struct sys_timer timer1 =
{
    .init   = timer_init,
};


|
整个流程没看懂
不知道你的多进程调度是什么意思?每个进程都会如何操作内核数据
不过你的代码完全没有考虑互斥
应该使用信号量来保护临界资源

|
是不是要加这儿加timer_interrupt开中断和关中断呢
{
关中断
clk_event.event_handler(&clk_event); 
开中断
}

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间java.sql类types的类成员方法: struct定义及介绍
  • linux 下结构struct ethhdr,struct iphdr在那个头文件下;谢谢!!
  • java命名空间java.sql接口struct的类成员方法: getsqltypename定义及介绍
  • typedef_struct与struct之间的区别
  • java命名空间java.sql接口struct的类成员方法: getattributes定义及介绍
  • struct sock *sk和 struct sk_buff *skb之间的关系
  • 知道TCP/UDP的包头,如何判断其应用层协议类型,struct tcphdr和 struct udphdr结构中那个变量能判断应用层协议类型。
  • struct task_struct * get_current(void)函数的解释--help!!
  • 任意struct問題
  • Linux内核中work_struct的定义
  • struct 也有构造器吗?
  • struct dirent的问题
  • 关于struct timespec的一个问题
  • 没有名字的struct
  • struct in_addr 和 unsigned long的转换
  • 求解struct的大小
  • Python struct.unpack
  • 请教struct sembuf的结构是怎样,急!急!急!!!!!!!!
  • 请问:从哪个header文件中看struct tty_driver的定义
  • 用g++开发,怎么设置结构(struct)1字节对齐?
  • struct timeval结构体的作用是什么呢?谢谢


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3