9.1实例一
9.1.1驱动程序
- /******************************
- * LED_Driver 2007/09/20
- *****************************/
- #include<linux/config.h>
- #include<linux/kernel.h>
- #include<linux/sched.h>
- #include<linux/timer.h>
- #include<linux/init.h>
- #include<linux/module.h>
- #include<asm/hardware.h>
- #defineGPIO_LED_MAJOR 97
- #defineARM_GPIO_LED_DEBUG
- #defineARM_GPIO_LED (GPIO96)
- #defineLED_ON 0
- #defineLED_OFF 1
- #definectl_GPIO_LED1 1
- #defineVERSION "ARM_GPIO_LED_2007/09/20"
- voidshowversion(void)
- {
- printk("*********************************************\n");
- printk("\t %s \t\n",VERSION);
- printk("********************************************\n\n");
- }
- //------------------- READ ------------------------
- ssize_tGPIO_LED_read (struct file * file ,char * buf, size_t count, loff_t * f_ops)
- {
- #ifdef ARM_GPIO_LED_DEBUG
- printk ("GPIO_LED_read [--kernel--]\n");
- #endif
- return count;
- }
- //------------------- WRITE -----------------------
- ssize_tGPIO_LED_write (struct file * file ,const char * buf, size_t count, loff_t *f_ops)
- {
- #ifdef ARM_GPIO_LED_DEBUG
- printk("GPIO_LED_write [ --kernel--]\n");
- #endif
- return count;
- }
- //------------------- IOCTL -----------------------
- ssize_tGPIO_LED_ioctl (struct inode * inode ,struct file * file, unsigned int cmd,long data)
- {
- #ifdef ARM_GPIO_LED_DEBUG
- printk("GPIO_LED_ioctl [ --kernel--]\n");
- #endif
- switch (cmd)
- {
- case LED_ON : {GPCR3 |= 0x1;break;}
- case LED_OFF: {GPSR3 |= 0x1;break;}
- default :
- {printk ("lcdcontrol : no cmd run [ --kernel--]\n"); return (-EINVAL);}
- }
- return 0;
- }
- //------------------- OPEN ------------------------
- ssize_tGPIO_LED_open (struct inode * inode ,struct file * file)
- {
- #ifdef ARM_GPIO_LED_DEBUG
- printk("GPIO_LED_open [ --kernel--]\n");
- #endif
- MOD_INC_USE_COUNT;
- return 0;
- }
- //------------------- RELEASE/CLOSE ---------------
- ssize_tGPIO_LED_release (struct inode * inode,struct file * file)
- {
- #ifdef ARM_GPIO_LED_DEBUG
- printk ("GPIO_LED_release [ --kernel--]\n");
- #endif
- MOD_DEC_USE_COUNT;
- return 0;
- }
- //-------------------------------------------------
- structfile_operations GPIO_LED_ctl_ops ={
- open: GPIO_LED_open,
- read: GPIO_LED_read,
- write: GPIO_LED_write,
- ioctl: GPIO_LED_ioctl,
- release: GPIO_LED_release,
- };
- //------------------- INIT ------------------------
- staticint __init HW_GPIO_LED_CTL_init(void)
- {
- int ret = -ENODEV;
- printk("Driver Loding.....................\n\n");
- showversion();
- // init GPIO
- GPDR3 |= 0x00000001; // SET GPIO96 OUTPUTMODE
- GPSR3 |= 0x00000001; // OFF THE LED
- #ifdef ARM_GPIO_LED_DEBUG
- printk (" GPLR3=%x\n",GPLR3);
- printk (" GPDR3=%x \n",GPDR3);
- #endif
- ret = devfs_register_chrdev(GPIO_LED_MAJOR,"led_drv", &GPIO_LED_ctl_ops);
- if( ret < 0 )
- {
- printk (" ARM: init_module failedwith %d\n [ --kernel--]", ret);
- return ret;
- }
- else
- {
- printk(" ARM gpio_led_driverregister success!!! [ --kernel--]\n");
- }
- return ret;
- }
- staticint __init ARM_GPIO_LED_CTL_init(void)
- {
- int ret = -ENODEV;
- #ifdef ARM_GPIO_LED_DEBUG
- printk("ARM_GPIO_LED_CTL_init [ --kernel--]\n");
- #endif
- ret = HW_GPIO_LED_CTL_init();
- if (ret)
- return ret;
- return 0;
- }
- staticvoid __exit cleanup_GPIO_LED_ctl(void)
- {
- #ifdef ARM_GPIO_LED_DEBUG
- printk("cleanup_GPIO_LED_ctl [ --kernel--]\n");
- #endif
- devfs_unregister_chrdev (GPIO_LED_MAJOR,"gpio_led_ctl" );
- }
- MODULE_DESCRIPTION("GPIO_led driver module");
- MODULE_AUTHOR("zsm");
- MODULE_LICENSE("GPL");//GPL协议证书信息
- module_init(ARM_GPIO_LED_CTL_init);
- module_exit(cleanup_GPIO_LED_ctl);
9.1.2用户程序
在编写用户应用程序过程中,考虑通过接口open()函数打开设备,再通过接口ioctl()函数来实现对LED的控制功能。
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <fcntl.h> // open() close()
- #include <unistd.h> // read() write()
- #define DEVICE_NAME "/dev/led_drv"
- #define LED_ON 0
- #define LED_OFF 1
- int main(void)
- {
- intfd;
- int ret;
- char *i;
- printf("\nstart GPIO_led_driver test\n\n");
- fd= open(DEVICE_NAME, O_RDWR);
- printf("fd= %d\n",fd);
- if(fd == -1)
- {
- printf("open device %s error\n",DEVICE_NAME);
- }
- else
- {
- while(1)
- { ioctl(fd,LED_OFF);
- sleep(1);
- ioctl(fd,LED_ON);
- sleep(1);
- }
- ret =close(fd);
- printf("ret=%d\n",ret);
- printf("close led_driver test\n");
- }
- return 0;
- }
9.1.3执行效果
(1)Create:
[root@OURSELEC usb]# mknod /dev/led_drv c 97 0
(2)view:
[root@OURSELEC usb]# ls -l /dev/led_drv
crw-r--r-- 1 root root 97, 0 Jan 1 01:29 /dev/led_drv
(3)insmod:
[root@OURSELEC usb]# insmod led_drv.o
Using led_drv.o
ARM_GPIO_LED_CTL_init [ --kernel--]
Driver Loding .....................
*********************************************
ARM_GPIO_LED_2007/09/20
*********************************************
GPLR3=73e7fd
GPDR3=1efffc3
ARMgpio_led_driver register success!!! [ --kernel--]
(4)./test_led:
[root@OURSELEC usb]# ./test_led
startGPIO_led_driver test
GPIO_LED_open[ --kernel--]
fd = 3
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_ioctl [ --kernel--]
GPIO_LED_release [ --kernel--]
(5) remove led_drv mode:
[root@OURSELEC usb]# rmmod led_drv
cleanup_GPIO_LED_ctl [ --kernel--]
9.2实例二
- /*************************************
- NAME:gt2440_leds.c
- COPYRIGHT:www.e-online.cc
- *************************************/
- #include <linux/miscdevice.h>
- #include <linux/delay.h>
- #include <asm/irq.h>
- #include <mach/regs-gpio.h>
- #include <mach/hardware.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/mm.h>
- #include <linux/fs.h>
- #include <linux/types.h>
- #include <linux/delay.h>
- #include <linux/moduleparam.h>
- #include <linux/slab.h>
- #include <linux/errno.h>
- #include <linux/ioctl.h>
- #include <linux/cdev.h>
- #include <linux/string.h>
- #include <linux/list.h>
- #include <linux/pci.h>
- #include <asm/uaccess.h>
- #include <asm/atomic.h>
- #include <asm/unistd.h>
- #define DEVICE_NAME "leds"
- /* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
- #define IOCTL_LED_ON 1
- #define IOCTL_LED_OFF 0
- /* 用来指定LED所用的GPIO引脚 */
- static unsigned long led_table [] =
- {
- S3C2410_GPB5,
- S3C2410_GPB6,
- S3C2410_GPB7,
- S3C2410_GPB8,
- };
- /* 用来指定GPIO引脚的功能:输出 */
- static unsigned int led_cfg_table [] =
- {
- S3C2410_GPB5_OUTP,
- S3C2410_GPB6_OUTP,
- S3C2410_GPB7_OUTP,
- S3C2410_GPB8_OUTP,
- };
- static int gt2440_leds_ioctl(
- structinode *inode,
- structfile *file,
- unsignedint cmd,
- unsignedlong arg)
- {
- if(arg > 4)
- {
- return-EINVAL;
- }
- switch(cmd)
- {
- caseIOCTL_LED_ON:
- //设置指定引脚的输出电平为0
- s3c2410_gpio_setpin(led_table[arg], 0);
- return0;
- caseIOCTL_LED_OFF:
- //设置指定引脚的输出电平为1
- s3c2410_gpio_setpin(led_table[arg], 1);
- return0;
- default:
- return-EINVAL;
- }
- }
- static struct file_operations dev_fops = {
- .owner = THIS_MODULE,
- .ioctl = gt2440_leds_ioctl,
- };
- static struct miscdevice misc = {
- .minor= MISC_DYNAMIC_MINOR,
- .name= DEVICE_NAME,
- .fops= &dev_fops,
- };
- static int __init dev_init(void)
- {
- intret;
- inti;
- for(i = 0; i < 4; i++)
- {
- s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]);
- s3c2410_gpio_setpin(led_table[i], 0);
- }
- ret= misc_register(&misc);
- printk(DEVICE_NAME" initialized\n");
- returnret;
- }
- static void __exit dev_exit(void)
- {
- misc_deregister(&misc);
- }
- module_init(dev_init);
- module_exit(dev_exit);
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("www.e-online.cc");
- MODULE_DESCRIPTION("LEDS control forGT2440 Board");