Linux驱动:内核延时测试
2012-12-07 13:57
525 查看
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:Fedora12
目标板:MINI6410
目标板LINUX内核版本:2.6.38
实现功能:
延迟2S
方法1:利用系统全局变量jiffies
jiffies记录系统节拍,每一次节拍,内核时钟中断函数会将jiffies加1.
HZ在ARM中为100,表示1S被分为100份,系统每个节拍为10ms.
修改上篇《linux驱动编写:LED驱动测试》中的ioctl函数,测试延时
[cpp] view
plaincopy
<span style="font-family:'Arial Black';font-size:18px;">//功能:ioctl操作函数
//返回值:成功返回0
static long led_driver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned int temp = 0;
unsigned long t = 0;
temp = readl(S3C64XX_GPKDAT);
if (cmd == 0)
{
temp &= ~(1 << (arg + 3));
}
else
{
temp |= 1 << (arg + 3);
}
//等待2S
t = jiffies;
while (time_after(jiffies,t + 2 * HZ) != 1);
writel(temp,S3C64XX_GPKDAT);
printk (DEVICE_NAME"\tjdh:led_driver cmd=%d arg=%d jiffies = %d\n",cmd,arg,jiffies);
return 0;
}</span>
这个方法会使内核忙等待,会影响系统效率.
2.利用宏ndelay(n),延时ns
udelay(n),延时us
mdelay(n),延时ms
这个简单,不做介绍
3.利用内核进行延时
long sleep_on_timeout(wait_queue_head 8q,long time_out);
long interruptible_sleep_on_timeout(wait_queue_head 8q,long time_out);
第2个与第1个相比差别在于会被中断唤醒。调用这两个函数,内核会阻塞当前进程,将其放入等待队列,等待时间到。
代码:
[cpp] view
plaincopy
<span style="font-family:'Arial Black';font-size:18px;">//功能:ioctl操作函数
//返回值:成功返回0
static long led_driver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned int temp = 0;
//unsigned long t = 0;
wait_queue_head_t wait;
temp = readl(S3C64XX_GPKDAT);
if (cmd == 0)
{
temp &= ~(1 << (arg + 3));
}
else
{
temp |= 1 << (arg + 3);
}
//等待2S
//t = jiffies;
//while (time_after(jiffies,t + 2 * HZ) != 1);
init_waitqueue_head(&wait);
sleep_on_timeout(&wait,2 * HZ);
writel(temp,S3C64XX_GPKDAT);
printk (DEVICE_NAME"\tjdh:led_driver cmd=%d arg=%d jiffies = %d\n",cmd,arg,jiffies);
return 0;
}
环境:
主机:Fedora12
目标板:MINI6410
目标板LINUX内核版本:2.6.38
实现功能:
延迟2S
方法1:利用系统全局变量jiffies
jiffies记录系统节拍,每一次节拍,内核时钟中断函数会将jiffies加1.
HZ在ARM中为100,表示1S被分为100份,系统每个节拍为10ms.
修改上篇《linux驱动编写:LED驱动测试》中的ioctl函数,测试延时
[cpp] view
plaincopy
<span style="font-family:'Arial Black';font-size:18px;">//功能:ioctl操作函数
//返回值:成功返回0
static long led_driver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned int temp = 0;
unsigned long t = 0;
temp = readl(S3C64XX_GPKDAT);
if (cmd == 0)
{
temp &= ~(1 << (arg + 3));
}
else
{
temp |= 1 << (arg + 3);
}
//等待2S
t = jiffies;
while (time_after(jiffies,t + 2 * HZ) != 1);
writel(temp,S3C64XX_GPKDAT);
printk (DEVICE_NAME"\tjdh:led_driver cmd=%d arg=%d jiffies = %d\n",cmd,arg,jiffies);
return 0;
}</span>
这个方法会使内核忙等待,会影响系统效率.
2.利用宏ndelay(n),延时ns
udelay(n),延时us
mdelay(n),延时ms
这个简单,不做介绍
3.利用内核进行延时
long sleep_on_timeout(wait_queue_head 8q,long time_out);
long interruptible_sleep_on_timeout(wait_queue_head 8q,long time_out);
第2个与第1个相比差别在于会被中断唤醒。调用这两个函数,内核会阻塞当前进程,将其放入等待队列,等待时间到。
代码:
[cpp] view
plaincopy
<span style="font-family:'Arial Black';font-size:18px;">//功能:ioctl操作函数
//返回值:成功返回0
static long led_driver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned int temp = 0;
//unsigned long t = 0;
wait_queue_head_t wait;
temp = readl(S3C64XX_GPKDAT);
if (cmd == 0)
{
temp &= ~(1 << (arg + 3));
}
else
{
temp |= 1 << (arg + 3);
}
//等待2S
//t = jiffies;
//while (time_after(jiffies,t + 2 * HZ) != 1);
init_waitqueue_head(&wait);
sleep_on_timeout(&wait,2 * HZ);
writel(temp,S3C64XX_GPKDAT);
printk (DEVICE_NAME"\tjdh:led_driver cmd=%d arg=%d jiffies = %d\n",cmd,arg,jiffies);
return 0;
}
相关文章推荐
- Linux驱动:内核延时测试
- 基于MPC8308的gpio管脚驱动测试linux2.6内核任务切换延时
- andriod驱动之旅-在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序(4)
- LINUX2.6.26.6内核下双口RAM的驱动函数测试成功!
- Linux2.6内核下简单的字符设备驱动及测试
- Linux驱动:用户空间,内核空间内存交互测试
- linux内核编译 驱动测试
- Linux2.6内核TouchScreen驱动移植(已测试)
- 【Linux开发】linux设备驱动归纳总结(七):1.时间管理与内核延时
- 编译和安装linux内核2.6.24,并且写一个简单的内核驱动测试之
- linux驱动之内核空间几种长延时的实现策略的优劣评估
- 编译和安装linux内核2.6.x,一个简单的内核驱动测试
- AM335X 串口驱动学习(1)-基于linux3.8内核
- 【转】 linux内核移植和驱动添加(三)
- FL2440移植LINUX-3.4.2 (七)--驱动移植LCD(移植自己写的和移植内核自带的)
- linux高级字符设备驱动之 二 内核等待队列
- lcd驱动移植的分析linux3.2内核,chipsee为例,液晶屏AT070TN92
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- 从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响
- Linux驱动开发必看详解神秘内核(完全转载)