当前位置: 技术问答>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,
};
#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);
开中断
}
{
关中断
clk_event.event_handler(&clk_event);
开中断
}
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。