linux驱动程序设计实例.doc
《linux驱动程序设计实例.doc》由会员分享,可在线阅读,更多相关《linux驱动程序设计实例.doc(18页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、AT91SAM9G20驱动程序设计开发环境:Vmware + ubuntu10.04硬件平台:AT91SAM9G20Linux版本:linux2.6.27一:led驱动说明:因为设计的开发板上没有led灯,便通过PC0来演示,通过示波器来观察引脚端的电平变化。1.驱动程序:my_led.c#include #include #include #include #include #include #include #define MY_LED_MAJOR250/定义主设备号#define LED_ON 0#define LED_OFF 1struct global_devstruct cdev
2、cdev;/定义设备结构体struct global_dev *global_devp;/定义一个指向设备结构体的指针static int my_led_open(struct inode *inode, struct file *filp)filp-private_data = global_devp;return 0;static int my_led_release(struct inode *inode, struct file *file)return 0;static int my_led_ioctl(struct inode *inode, struct file *filp,
3、unsigned int cmd, unsigned long data)switch(cmd)case LED_ON:at91_set_gpio_value(AT91_PIN_PC0, 0);/将PC0引脚置低break;case LED_OFF:at91_set_gpio_value(AT91_PIN_PC0, 1);/将PC1引脚置高break;default:printk(no valid cmd input!n);break;return 0;struct file_operations my_led_ctl_ops =.owner = THIS_MODULE,.open = my_
4、led_open,.release = my_led_release,.ioctl = my_led_ioctl,;/*初始化设备结构体*/static void my_led_setup(struct global_dev *dev, int index)int err;int devno = MKDEV(MY_LED_MAJOR, index);cdev_init(&dev-cdev, &my_led_ctl_ops);dev-cdev.owner = THIS_MODULE;dev-cdev.ops = &my_led_ctl_ops;err = cdev_add(&dev-cdev,
5、devno, 1);if(err)printk(add my led setup failed!n);static int my_led_init(void)int ret;dev_t devno = MKDEV(MY_LED_MAJOR, 0);/创建设备号printk(my first driver-led!n);at91_set_GPIO_periph(AT91_PIN_PC0, 1);at91_set_gpio_output(AT91_PIN_PC0, 1);/对PC0引脚的初始化ret = register_chrdev_region(devno, 1, my_led);/申请设备号
6、if( ret cdev);/删除设备kfree(global_devp);/释放内存unregister_chrdev_region(MKDEV(MY_LED_MAJOR, 0), 1);/释放设备号MODULE_LICENSE(MYGPL);MODULE_AUTHOR(FANY);module_init(my_led_init);/注册设备module_exit(my_led_cleanup);/卸载设备2:如何将驱动驱动程序编译成模块在drivers目录下新建led目录,并在该目录下添加Kconfig,Makefile文件。Kconfig:Menu My driver supportCo
7、nfig Trisate led driver!Help Led driverEndmenu:Makefile:Obj-$(CONFIG_MY_LED)+= my_led.o修改linux/drivers目录下的Kconfig,Makefile文件Kconfig:Source drivers/led/KconfigMakefile:Obj-y += my_led/修改体系结构目录arch/arm目录下的Kconfig文件,否则在配置菜单中将无法看到led的配置选项。(如果是在drivers目录下新建一文件夹,并在其中添加驱动程序,必须相应的体系结构目录下添加配置选项)。Kconfig:Sour
8、ce driver/led/Kconfig3.测试程序:my_led_test.c#include #include #include #include #include #define DEVICE_NAME /dev/my_led#define LED_ON0#define LED_OFF 1int main(void)int fd;int ret;int i;printf(my_led_driver test!n);fd = open(DEVICE_NAME, O_RDONLY);if(fd = -1)printf(open device %s error!n, DEVICE_NAME)
9、;for(i = 0; i 50; i+)ioctl(fd, LED_OFF);sleep(1);ioctl(fd, LED_ON);sleep(1);ret = close(fd);printf(ret = %dn, ret);printf(close my_led_driver!n);return 0;将测试程序编译成目标平台的可执行文件,并下载到开发板GCC=/home/zzq/9G20/arm-2007q1/bin/arm-none-linux-gnueabi-gcc #交叉编译器的路径My_led_test:my_led_test.c $(GCC) -o my_led_test my
10、_led_test.cclean: rm -f my_led_test学习总结:熟悉驱动程序的架构,如何将驱动程序添加到内核即如何写测试程序。二:按键驱动设计1.硬件部分:PC4接按键。2.驱动程序:#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUTTON_MAJOR245#define DEVICE_
11、NAME /dev/buttonstatic volatile int ev_press = 0;static struct cdev button_cdev;static void button_do_tasklet(unsigned long n);DECLARE_TASKLET(button_tasklet, button_do_tasklet, 0);/定义tasklet并与处理函数关联起来static DECLARE_WAIT_QUEUE_HEAD(button_waitq);/静态的初始化一个等待队列struct button_irq_desc int irq;int irq_ty
12、pe;int pin;int number;char *name;static struct button_irq_desc button_irq1 = AT91_PIN_PB22, AT91_AIC_SRCTYPE_LOW, AT91_PIN_PB22, 0, KEY0 ;static int key_values1=0;/中断处理底半部static void button_do_tasklet(unsigned long n)wake_up_interruptible(&button_waitq);/唤醒队列printk(button press!n);/中断处理顶半部static irq
13、return_t button_interrupt(int irq, void *dev_id, struct pt_regs *regs)int up; static int press_down;up = gpio_get_value(button_irq0.pin);printk(irqn);/*按键消抖*/if(up)press_down = 1;/当按键没有按下,置标志位为1.if(!up & (press_down = 1) press_down = 0; /当按键按下,置标志位为0.ev_press = 1;at91_set_gpio_value(button_irq0.pin,
14、 1);key_valuesbutton_irq0.number = !up;tasklet_schedule(&button_tasklet);return IRQ_RETVAL(IRQ_HANDLED);static int button_open(struct inode *inode, struct file *filp)return 0;static int button_release(struct inode *inode, struct file *filp)return 0;static int button_read(struct file *filp, char _use
15、r *buff, size_t count, loff_t *offp)int ret;if(!ev_press) /当按键没有按下时,读进程挂起,知道按键按下。wait_event_interruptible(button_waitq, ev_press);ev_press = 0;ret = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count);memset(void _user *)key_values, 0, sizeof(key_values);return ret ? -EFAULT:
16、min(sizeof(key_values), count); static struct file_operations button_fops = .owner = THIS_MODULE,.open = button_open,.release = button_release,.read = button_read,;static int irq_init(void)int err;at91_set_gpio_input(button_irq0.pin, 1);at91_set_deglitch(button_irq0.pin, 1);/将PC0设置为中断功能set_irq_type(
17、button_irq0.irq, button_irq0.irq_type);/设置中断类型at91_set_gpio_value(button_irq0.pin, 1);err = request_irq( button_irq0.irq, button_interrupt, IRQF_DISABLED, button_irq0.name, (void *)&button_irq0);/申请中断if ( err ) disable_irq(button_irq0.irq);free_irq(button_irq0.irq, (void *)&button_irq0);return -EBUS
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 驱动程序 设计 实例
限制150内