函数的可重入性问题:
判断一个函数是否具有可重入性的标准,就是函数是否使用了全局变量
如果使用了全局变量,那么它就不具有可重入性
1.中断处理函数的特点:
1)短而有效率(很快直接结束)
中断处理函数中不应该调用那些执行速度比较慢 比较耗时子函数
2)Linux中断处理函数中,不能调用引起阻塞或者睡眠的函数
copy_to_user / copy_from_user / msleep
3)Linux系统中中断处理函数运行于中断上下文,
使用独立的栈空间,该栈空间通常为1个物理内存页(4KB)意味着中断处理函数中不应该分配静态大数组
每个线程有独立的栈空间,有两个栈,一个是内核态,一个是用户态
Linux系统支持大量硬件设备
往往有些硬件产生中断后,中断处理函数执行速度快不了
例如网卡,接收数据后会产生中断,处理大量的数据和各阶层协议
为了解决该矛盾,linux系统中将中断整个处理过程人为的分为两个半部
1)顶半部 top half: 完成那些最紧急的工作
往往是一些特殊功能寄存器的读写操作
退出中断前要完成底半部的登记
执行完毕后就退出中断
2)底半部 bottom half: 完成那些耗时的不太紧急的工作
2、底半部登记的方式
2.1 软中断
需要修改内核源码,不能以模块形式出现
用起来不方便
2.2 tasklet
基于软中断机制实现的
核心数据结构
struct tasklet_struct //interrupt.h
{
//保存底半部函数的地址
void (*func)(unsigned long);
//系统调用func时传递给func的参数值
unsigned long data;
...
};
使用步骤:
1)定义一个tasklet变量
struct tasklet_struct btn_tasklet;
2) 初始化tasklet变量
void tasklet_init(struct tasklet_struct *t,
void (*func)(unsigned long), unsigned long data)
以上两步也可以使用DECLARE_TASKLET(name, func, data)来替换,使用此宏直接放在函数外面就可以
例如:DECLARE_TASKLET(btn_tasklet, btn_tasklet_func, (unsigned int)&mydata);
3)使用tasklet变量完成底半部的登记
void tasklet_schedule(struct tasklet_struct *t)
实验代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <mach/platform.h>
#include <linux/delay.h>
MODULE_LICENSE("GPL");
typedef struct btn_desc
{
char *name ;//名称
int irq;//中断号
}btn_desc_t;
btn_desc_t buttons[]={
{
"up", IRQ_GPIO_A_START+28},
{
"down", IRQ_GPIO_B_START+30},
{
"left", IRQ_GPIO_B_START+31},
{
"right", IRQ_GPIO_B_START+9},
};
/*定义一个tasklet变量*/
struct tasklet_struct btn_tasklet;
/*
*irq, 中断号
*dev, 注册时给定的最后一个参数
* */
irqreturn_t btn_isr(int irq, void *dev)
{
btn_desc_t *pdata = dev;
printk("<2>" "enter top half do emerg things ....\n");
printk("<2>" "%s key is pressed!\n", pdata->name);
/*登记底半部*/
printk("<2>" "register bottom half\n");
tasklet_schedule(&btn_tasklet);
printk("<2>" "exit from top half\n");
/*中断出来完毕*/
return IRQ_HANDLED;
}
int mydata = 0x100;
void btn_tasklet_func(unsigned long data)
{
int *pdata = (int *)data;
printk("<2>" "enter bottom half: do no emerg things....\n");
printk("<2>"