linux内核机制中的中断

来源:互联网 发布:金克丝神龙烈焰淘宝 编辑:程序博客网 时间:2024/05/17 04:04

20131008

国庆回来第二天: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查看是否有udevudevadm这两个文件;

#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

 

原创粉丝点击