点亮led过程分析
来源:互联网 发布:数据储存 编辑:程序博客网 时间:2024/05/19 02:29
在mini2440中,led,按键等驱动默认已经被编译入内核,所以一直不知道同一个硬件设备资源能不能作为多个模块,编译入内核。
故重写了一个myled.ko,系统默认是led.ko,并用应用程序检测。
myled.c
#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/types.h>#include <linux/gpio.h>#include <linux/ioctl.h>#include <linux/cdev.h>#include <linux/mm.h>#include <linux/device.h>#include <mach/regs-gpio.h>#include <mach/hardware.h>#include <asm/uaccess.h>#include <asm/atomic.h>#include <asm/unistd.h>//**************static struct device *dev;//*************#define DEVICE_NAME "myled"static struct cdev *cdevp=NULL;//定义一个cdev结构体,并初始化static dev_t devno;//定义一个设备号static unsigned long led_table[] = { S3C2410_GPB(5),//定义端口 S3C2410_GPB(6), S3C2410_GPB(7), S3C2410_GPB(8),};static unsigned int led_cfg_table[] = { S3C2410_GPIO_OUTPUT,//定义寄存器状态 S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT, S3C2410_GPIO_OUTPUT,};static int s3c2440_leds_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){ switch(cmd) { case 0: case 1: if(arg>3) { return -EINVAL; } s3c2410_gpio_setpin(led_table[arg],!cmd); return 0; default: return -EINVAL; }}//应用程序与驱动映static struct file_operations myled_fops = { .owner = THIS_MODULE, .ioctl = s3c2440_leds_ioctl,};//**************static struct class *led_class;//**************static int __init myled_init_module(void){ int ret; int i,err; ret = alloc_chrdev_region(&devno,0,1,DEVICE_NAME);//注册设备 if(ret < 0) { printk(DEVICE_NAME "can't get the major number\n"); return ret; }//**************************** led_class= class_create(THIS_MODULE,DEVICE_NAME); if(IS_ERR(led_class)){printk("Err: failed in leds-class.\n");return -1;} dev=device_create(led_class,NULL,devno,NULL,DEVICE_NAME);//************************** cdevp = cdev_alloc();//动态申请一个cdev内存 cdev_init(cdevp,&myled_fops);//初始化cdev cdevp->owner = THIS_MODULE; err=cdev_add(cdevp,devno,1); if(err) { printk(KERN_NOTICE "Error %d adding cdev",err); unregister_chrdev_region(devno,1); return -EFAULT; } for(i=0;i<4;i++) { s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]); s3c2410_gpio_setpin(led_table[i],1) } printk(DEVICE_NAME "\tinitialized! 2012-12-9\n"); return 0;}static void __exit myled_exit_module(void){ cdev_del(cdevp); unregister_chrdev_region(devno,1);//**************** device_destroy(led_class,devno); class_destroy(led_class);/***************** printk(DEVICE_NAME "\tunloaded by tong2012-12-9\n");}module_init(myled_init_module);module_exit(myled_exit_module);MODULE_LICENSE("GPL");MODULE_AUTHOR("tong 2012-12-9");
Makefile如下
ifneq ($(KERNELRELEASE),)obj-m:=myled.oelseKDIR := /opt/FriendlyARM/mini2440/linux-2.6.32.2_faall:make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-clean:rm -f *.ko *.o *.mod.o *.mod.c *.symversendif
拷贝到开发板上,insmod myled.ko可在/dev下生成设备节点myled.ko
现在采用系统给出的例程,但修改设备节点为myled,
led.c (必须使用交叉编译器)
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/ioctl.h>int main(int argc, char **argv){int on;int led_no;int fd;if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 || on < 0 || on > 1 || led_no < 0 || led_no > 3) {fprintf(stderr, "Usage: leds led_no 0|1\n");exit(1);}fd = open("/dev/myled", 0);if (fd < 0) {fd = open("/dev/myled", 0);}if (fd < 0) {perror("open device leds");exit(1);}ioctl(fd, on, led_no);close(fd);return 0;}
先用/etc/rc.d/init.d/leds stop关闭系统初始化中,开启的让四个led循环闪动的服务,
通过ioctl函数可以控制让哪个led,是亮还是灭,能成功。
说明了,同一个硬件设备资源能被作为多个模块,换成不同的名字,互不干扰,也就是说可以同时硬件资源可以为应用程序中的多种服务工作,可以联想一下智能手机是如何工作的。
- 点亮led过程分析
- Cortex A8 LED 点亮程序分析
- 点亮LED
- 点亮LED
- 点亮LED
- 点亮led
- 【51单片机学习过程记录】 2LED点亮
- mini2440之首个C程序点亮LED分析
- 1.点亮1个led程序分析(汇编)
- 1.点亮1个led程序分析(C语言)
- 基于Cortex-A8裸机,点亮LED灯程序分析
- PIC单片机之第一个工程分析,点亮LED
- 点亮一个LED
- 点亮一个LED
- TQ2440之LED点亮
- 点亮一个led
- MSP430F5438点亮led
- 点亮板载led
- 动态规划解最长公共子序列问题
- RSS解析技术的应用
- hibernate执行sql获取泛型对象
- java正则表达式
- apache shiro database
- 点亮led过程分析
- 设计模式之结构型模式一
- CET 四六级查分器
- 断章——卞之琳
- 银行IT部门科技管理流程管控工作发展之路
- Codeforces Round #134 (Div. 2)——B
- hibernate 乐观锁与悲观锁使用
- css定位详解
- 高仿QQ2012登录界面