linux内核机制中的中断
来源:互联网 发布:金克丝神龙烈焰淘宝 编辑:程序博客网 时间:2024/05/17 04:04
2013年10月08日
国庆回来第二天:135天
学习流程:
基础: 1.linux
2.开发板 ,arm汇编, c, 数据结构
3.C++,工具
应用: 1.posix(open,fork)
2.内核机制
3.网络*
驱动:
1.arm体系结构。
2.(设备)LCD驱动,网络驱动,触屏驱动,声卡驱动
项目:
1.bootloader(vivi三星公司中的两个bootloader中的另一个)
2.Android
开发平台:
s3c6410
soc的目前市场两家公司:
高通,三星
注意:
1.printk不处理浮点数:
2.内部中断与外部中断管理器相对于soc而言的,但都在soc上。
3.static int flag = 1;static的作用域在离他最近的上一个花括号到下一个花括号之间。
1.中断中的相关函数:
set_irq_type();==>外部中断
resquest_irq();==》中断注册函数
例按键:(外部中断)
set_irq_type(IRQ_EINT(0),IRQ_TYPE_EDGE_FALLING);外部中断的类型为下降沿
ret2 = request_irq(IRQ_EINT(0),this->do_irq,IRQF_SHARED,"s2",this);
例看门狗:(内部中断)
ret = request_irq(IRQ_WDT,this->do_irq,IRQF_SHARED,"led",this);
小题练习:
1.按一下按键,就灯亮;再按一下灯就灭;
2.按一下按键,灯闪;再按一下灯就灭;
3.按一下s2灯慢闪;按一下s3就快闪;
第一是题:
//按一按键,灯亮;再按一下,灯就灭
#include <linux/init.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/interrupt.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("you");
unsigned long led_virt;
unsigned long *gpmcon,*gpmdat;
void led_on();
void led_off();
irqreturn_t do_irq(int irq,void *data);
int test_init()
{
int ret,ret2;
led_virt = ioremap(0x7F008820,SZ_4K);
gpmcon = led_virt+0x00;
gpmdat = led_virt+0x04;
set_irq_type(IRQ_EINT(0),IRQ_TYPE_EDGE_FALLING);
ret = request_irq(IRQ_EINT(0),do_irq,IRQF_SHARED,"s2",0x5555);
if(ret<0)
{
printk("request irq\n");
return ret;
}
return 0;
}
void test_exit()
{
printk("exit module\n");
}
module_init(test_init);
module_exit(test_exit);
irqreturn_t do_irq(int irq,void *data)
{
printk("s2 down\n");
static int flag = 1;
if(flag)
led_on();
else
led_off();
flag ^= 1;
return IRQ_HANDLED;
}
void led_on()
{
*gpmcon = 1;
*gpmdat = 0;
}
void led_off()
{
*gpmcon = 1;
*gpmdat = 1;
}
编写Makefile在最下面有
make
将make后生成的test.ko 拷贝到/mynfsroot/lib/module/2.6.28.6/
在板子上进入test.ko所在文件的目录中,insmod test.ko
最后移除:rmmod test
第二题:
2.按一下按键,灯闪;再按一下灯就灭;
/按一下灯闪,再按一下灯灭
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("you");
struct dev{
unsigned long wdt_virt;
unsigned long *wtcon,*wtdat,*wtcnt,*wtclrint;
unsigned long led_virt;
unsigned long *gpmcon,*gpmdat;
int (*init_dev)(struct dev *this);
void (*exit_dev)(struct dev *this);
void (*led_on)(struct dev *this);
void (*led_off)(struct dev *this);
void (*wdt_on)(struct dev *this);
void (*wdt_off)(struct dev *this);
irqreturn_t (*do_irq)(int irq,struct dev *this);
};
int my_init_dev(struct dev *this);
void my_exit_dev(struct dev *this);
void my_led_on(struct dev *this);
void my_led_off(struct dev *this);
void my_wdt_on(struct dev *this);
void my_wdt_off(struct dev *this);
irqreturn_t my_do_irq(int irq,struct dev *this);
struct dev led;
int test_init(void)
{
led.init_dev = my_init_dev;
led.exit_dev = my_exit_dev;
led.init_dev(&led);
return 0;
}
void test_exit(void)
{
led.exit_dev(&led);
}
module_init(test_init);
module_exit(test_exit);
void my_exit_dev(struct dev *this)
{
iounmap(this->wdt_virt);
iounmap(this->led_virt);
free_irq(IRQ_WDT,this);
free_irq(IRQ_EINT(0),this);
printk("goodbye module");
}
int my_init_dev(struct dev *this)
{
int ret2,ret;
this->led_on = my_led_on;
this->led_off = my_led_off;
this->wdt_on = my_wdt_on;
this->wdt_off = my_wdt_off;
this->do_irq = my_do_irq;
set_irq_type(IRQ_EINT(0),IRQ_TYPE_EDGE_FALLING);
ret2 = request_irq(IRQ_EINT(0),this->do_irq,IRQF_SHARED,"s2",this);
if(ret2<0)
{
printk("request irq\n");
return 1;
}
ret = request_irq(IRQ_WDT,this->do_irq,IRQF_SHARED,"led",this);
if(ret<0)
{
printk("request irq\n");
return 1;
}
this->wdt_virt = ioremap(0x7E004000,SZ_4K);//物理地址找到对应的虚拟地址
this->wtcon = (void *)(this->wdt_virt + 0x00);
this->wtdat = (void *)(this->wdt_virt + 0x04);
this->wtcnt = (void *)(this->wdt_virt+0x08);
this->wtclrint = (void *)(this->wdt_virt+0x0c);
// this->wdt_on(this);
this->led_virt = ioremap(0x7F008000,SZ_4K);
this->gpmcon = (void *)(this->led_virt+0x820);
this->gpmdat = (void *)(this->led_virt+0x824);
return 0;
}
irqreturn_t my_do_irq(int irq,struct dev *this){
if(irq == IRQ_EINT(0))
{
static int flag = 1;
printk("s2 down\n");
if(flag)
this->wdt_on(this);
else{
this->wdt_off(this);
this->led_off(this);
}
flag ^= 1;
}
if(irq == IRQ_WDT)
{
static int flag = 1;
*this->wtclrint = 0;
if(flag)
this->led_on(this);
else{
this->led_off(this);
}
flag ^= 1;
}
return IRQ_HANDLED;
}
void my_led_on(struct dev*this)
{
*this->gpmcon = 1;
*this->gpmdat = 0;
}
void my_led_off(struct dev *this)
{
*this->gpmcon = 1;
*this->gpmdat = 1;
}
void my_wdt_on(struct dev *this)
{
*this->wtcon = (1<<2)|(2<<3)|(1<<5)|(30<<8);
*this->wtdat = 0x8000;
*this->wtcnt = 0x8000;
}
void my_wdt_off(struct dev *this)
{
*this->wtcon = 0;
}
default:
make -C /home/linux-2.6.28_smdk6410 M=`pwd`
clean:
make -C /home/linux-2.6.28_smdk6410 M=`pwd` clean
rm -rf modules.order
obj-m +=test.o
2.系统的所有信息都放在/proc下面:
cat /proc/interrups
sys/目录下面:clss按功能化分;bus按总线划分;
3.自动创建在/sys/class中创建的设备文件,也会自动加入到/dev目录下面(给应用层提供一个接口)
在这个目录下面:/home/myfile/teacher_liu/smdk6410_resource/src/udev-128
CC=arm-none-linux-gnueabi-gcc ./configure --build=i386 --host=arm-linux --prefix=/mynfsroot --exec_prefix=/mynfsroot
make && make install
在/etc/init.d/rcS文件中添加一些内容:
在这个目录中/mynfsroot/sbin查看是否有udev与udevadm这两个文件;
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/kdev_t.h>
#include <linux/types.h>
#include <linux/device.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("you");
struct class *person;
struct device *chunge;
dev_t devno;
int test_init()
{
person = class_create(THIS_MODULE,"person");
if(IS_ERR(person))
{
PTR_ERR(person);
return 1;
}
devno = MKDEV(9,1);
chunge = device_create(person,NULL,devno,NULL,"chunge%d",1);
if(IS_ERR(chunge))
{
PTR_ERR(chunge);
return 1;
}
return 0;
}
void test_exit()
{
printk("exit module\n");
}
module_init(test_init);
module_exit(test_exit);
所有的Makefile文件:
default:
make -C /home/linux-2.6.28_smdk6410 M=`pwd`
clean:
make -C /home/linux-2.6.28_smdk6410 M=`pwd` clean
rm -rf modules.order
obj-m +=test.o
- linux内核机制中的中断
- linux内核--中断机制
- linux内核中断机制
- Linux内核中的中断
- 八。内核中的中断机制
- 参透Linux内核中断机制
- linux内核中断实现机制
- Linux内核的中断机制
- Linux内核的中断机制
- linux内核中断实现机制
- Linux中的中断机制 2
- Linux中的中断处理机制
- Linux 2.4.x内核软中断机制
- Linux 2.4.x内核软中断机制
- Linux内核的时钟中断机制(01)
- Linux 2.4.x内核软中断机制
- IA32上Linux内核中断机制分析
- Linux内核的时钟中断机制
- oracle group by
- 大端小端问题
- 输入输出流中 InputStream read方法 和 OutputStream write 方法的理解
- objective-c 内存自动释放(1)
- 谈谈android数据存储方式
- linux内核机制中的中断
- chapter05--车辆,乡村用水,一元二次方程的根,电视频道
- iOS7 uilabel 自动换行,文字自适应
- 快速搭建Android NDK环境
- 应用360云盘与SVN版本管理服务器搭建基于云端的版本控制软件
- cout << (a += a -= a*a)和cout << a += a -= a*a
- VisualStudio开发工具中的C#主流控件属性及事件汇总(菜鸟必备)
- 【leetcode】Add Binary
- HTK安装和测试