*针对不同的平台。可能放进的不是以下的文件内,仅仅做參考
1、头文件
放进:linux-3.0.8archarmplat-samsungincludeplat
led.h
#ifndef _HEAD_H
#define _HEAD_H
#define MAGIC 'h'
#define LED_ON _IOW(MAGIC,1,int)
#define LED_OFF _IOW(MAGIC,0,int)
struct led_device{
dev_t devno;
unsigned int led_major;
struct cdev *led_cdev;
struct class *led_class;
struct device *led_device;
};
#endif
====================================================================================================================================
2、设备文件
方法一:将设备资源直接加进/linux-3.0.8/arch/arm/mach-s5pv210下的mach-smdkv210.c
①
struct platform_device s5pv210_led_device_lhy = {
.name = 's5pv210_led_lhy',
.id = 1,
};
static struct platform_device *smdkv210_devices[] __initdata = {
。。
。。。
。
。。。
。。。
。
。。
。。
。。。
。。。
。。。。
}
②将设备信息加入总线
改动arch/arm/mach-s5pv210/mach-smdkv210.c文件
static struct platform_device *smdkv210_devices[] __initdata = {
...
...
/*加入例如以下代码*/
&s5pv210_led_device_lhy, //新加入的
}
方法二:
①将设备文件dev-led.c 放进 linux-3.0.8/arch/arm/plat-samsung
led_dev.c
#include #include #include #include struct platform_device s5pv210_led_device_lhy = { .name = 's5pv210_led_lhy', .id = 1, }; ②向arch/arm/mach-s5pv210/mach-smdkv210.c(跟平台架构相关文件)加入 static struct platform_device *smdkv210_devices[] __initdata = { .... &s5pv210_led_device_lhy, //新加入 }; ③向linux-3.0.8/arch/arm/plat-samsung/Makefile加入 obj-$(CONFIG_S3C_DEV_LED) += led_dev.o ④向linux-3.0.8/arch/arm/plat-samsung/Kconfig加入 config S3C_DEV_LED bool 'S5PV210 LED driver support' help s5pv210 led device support ⑤加入外部声明arch/arm/plat-samsung/include/plat/devs.h extern struct platform_device s5pv210_led_device_lhy; ==================================================================================================================================== 3、平台驱动 ①将led_drv.c 放进linux-3.0.8/drivers/my_led led_drv.c #include #include #include #include #include #include #include #include #include //下面是移植时须要添加的 #include #include #include #include #include #include static struct led_device *led_drv; static int led_open(struct inode *inode, struct file *file) { printk(KERN_INFO'%s()-%dn', __func__, __LINE__); s3c_gpio_cfgpin(S5PV210_GPC0(3),S3C_GPIO_OUTPUT); s3c_gpio_cfgpin(S5PV210_GPC0(4),S3C_GPIO_OUTPUT); return 0; } static ssize_t led_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { printk(KERN_INFO'%s()-%dn', __func__, __LINE__); return count; } ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) { printk(KERN_INFO'%s()-%dn', __func__, __LINE__); return 0; } static long led_ioctl(struct file *file, unsigned int cmd, unsigned long val) { printk(KERN_INFO'%s()-%dn', __func__, __LINE__); printk(KERN_INFO'cmd=%d arg=%ldn', cmd, val); switch(cmd) { case LED_ON: gpio_set_value(S5PV210_GPC0(val),1); break; case LED_OFF: gpio_set_value(S5PV210_GPC0(val),0); break; default: break; } return 0; } //硬件操作方法 static struct file_operations led_fops={ .owner = THIS_MODULE, .open = led_open, .write = led_write, .read = led_read, .unlocked_ioctl = led_ioctl, }; static int s5pv210_led_probe(struct platform_device *pdrv){ int ret; led_drv = kmalloc(sizeof(struct led_device),GFP_KERNEL); if(led_drv==NULL){ printk(KERN_ERR'no memory malloc for fs210_ledn'); return -ENOMEM; } /*1. 动态注冊/申请主设备*/ ret=alloc_chrdev_region(&led_drv->devno,0,1,'dev_module'); if (ret < 0) { printk(KERN_ERR 'unable to get majorn'); return -EFAULT; goto out_err_1; } //从设备号中分离出主设备号 led_drv->led_major = MAJOR(led_drv->devno); /*为cdev分配空间*/ led_drv->led_cdev = cdev_alloc(); /*注冊硬件操作方法/初始化cdev*/ cdev_init(led_drv->led_cdev,&led_fops); /*注冊字符设备*/ cdev_add(led_drv->led_cdev,led_drv->devno,1); /*2. 创建设备类*/ led_drv->led_class=class_create(THIS_MODULE,'led_class'); if (IS_ERR(led_drv->led_class)) { printk(KERN_ERR 'class_create() failed for led_classn'); ret = -ENODATA; goto out_err_2; } /*3. 创建设备文件*/ led_drv->led_device=device_create(led_drv->led_class,NULL,MKDEV(led_drv->led_major,0),NULL,'led'); // /led/xxx if (IS_ERR(led_drv->led_device)) { printk(KERN_ERR 'device_create failed for led_devicen'); ret = -ENODEV; goto out_err_3; } /*申请GPC0_3,4引脚资源*/ gpio_request(S5PV210_GPC0(3),'LED1'); gpio_request(S5PV210_GPC0(4),'LED2'); return 0; out_err_3: class_destroy(led_drv->led_class); out_err_2: unregister_chrdev(led_drv->led_major,'led_module'); out_err_1: kfree(led_drv); return ret; } static int s5pv210_led_remove(struct platform_device *pdrv){ unregister_chrdev(led_drv->led_major,'led_module'); device_destroy(led_drv->led_class,MKDEV(led_drv->led_major,0)); class_destroy(led_drv->led_class); gpio_free(S5PV210_GPC0(3)); gpio_free(S5PV210_GPC0(4)); kfree(led_drv); return 0; } struct platform_device_id led_ids[]={ [0]={ .name = 's5pv210_led_lhy', .driver_data = 0, }, }; static struct platform_driver s5pv210_led_driver = { .probe = s5pv210_led_probe, .remove = s5pv210_led_remove, .driver = { .name = 's5pv210_led_lhy', .owner = THIS_MODULE, }, .id_table = led_ids, }; static int __devinit s5pv210_led_init(void) { return platform_driver_register(&s5pv210_led_driver); } static void __devexit s5pv210_led_exit(void) { platform_driver_unregister(&s5pv210_led_driver); } module_init(s5pv210_led_init); module_exit(s5pv210_led_exit); MODULE_DESCRIPTION('LED driver for Marvell PM860x'); MODULE_AUTHOR('kiron'); MODULE_LICENSE('GPL'); MODULE_ALIAS('platform:s5pv210-led'); ②在当前文件夹的Kconfig后加入,没有就新建 config S5PV210_LED_DRV tristate 'led_dev for fs210 device' help led driver is for s5pv210, choose y/m/n ③在当前文件夹的Makefile后加入,没有就新建 obj-$(CONFIG_S5PV210_LED_DRV) = led_drv.o ④改动上级文件夹的Makefile和Kconfig 将linux-3.0.8/drivers/Kconfig 加入 source 'drivers/my_led/Kconfig' 将linux-3.0.8/drivers/Makefile 加入 obj-y += mydriver/ 最后就是自己make menuconfig里配置选项了。 ==================================================================================================================================== 4、測试程序编译測试要使用交叉工具连 arm-none-linux-gnueabi-gcc led_test.c -o led_test 附: 将可运行文件增加到开机启动,改动根文件系统filesystem vi filesystem/etc/init.d/rcS ./star_app/led_test 測试程序 #include #include #include #include #include #include #include #include #include #define MAGIC 'h' #define LED_ON _IOW(MAGIC,1,int) #define LED_OFF _IOW(MAGIC,0,int) static void my_sleep(int n){ int j; for(j=0; j<10000000*n; j++); } int main(void) { printf('-------------------------------n' '|| start:一闪一闪亮晶晶 ||n' '-------------------------------n'); my_sleep(1); int fd; unsigned int cmd=0; unsigned long val=0; fd=open('/dev/led', O_RDWR); if(fd<0){ perror('open failed!n'); exit(1); } int i; for(i=0; i<10; i++){ if(i%2==0) cmd=LED_OFF; else cmd=LED_ON; val=3; //亮 led3 if(ioctl(fd,cmd,val)<0){ perror('ioctl failed!n'); exit(1); } val=4; //亮 led4 if(ioctl(fd,cmd,val)<0){ perror('ioctl failed!n'); exit(1); } my_sleep(1); } close(fd); return 0; }
上一篇:gpiolib库详解
下一篇:Linux下简易蜂鸣器驱动代码及测试实例
推荐阅读最新更新时间:2026-03-25 12:13
- 用于 7VIN 至 16VIN、1.5V 和 1.2V 输出的 LTM4628EV DC/DC 模块稳压器的典型应用电路
- 使用 Analog Devices 的 LTC3728LIGN 的参考设计
- DER-406 - 适用于 A19 灯的 5.76 W 高 PF 非隔离降压-升压型 TRIAC 调光 LED 驱动器
- ADR5045B 5V 输出精密微功率并联模式电压基准的典型应用
- LT3970EDDB-3.42 2.5V 降压转换器的典型应用
- MC78M08BDTG 8V 电流调节器的典型应用
- LT1021DCN8-5 精密电压基准的典型应用
- DER-282 - 100W, 扁平(11 mm), LLC DC-DC转换器
- REF193 低压差开尔文连接电压基准的典型应用电路
- LT3088EM 线性稳压器用于添加软启动的典型应用

DS1000Z数字示波器中文使用说明
【Follow me第三季第4期】英飞凌CY8CPROTO-063-BLE开发板全任务实战源码
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号