博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
喜羊羊系列之【设备-驱动 动态载入进内核】
阅读量:5102 次
发布时间:2019-06-13

本文共 5721 字,大约阅读时间需要 19 分钟。

博客:

这篇和做对照

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

平台设备

dev_led.c

#include 
#include
#include
#include "led.h"static void led_release(struct device *dev){ }static struct platform_device s5pv210_led_device_lhy = { .name = "s5pv210_led_lhy", .id = 1, .dev = { .release = led_release, //开发模式下,这个真不能少! },};static int __init dev_led_init(void){ platform_device_register(&s5pv210_led_device_lhy); return 0;}static void __exit dev_led_exit(void){ platform_device_unregister(&s5pv210_led_device_lhy);}module_init(dev_led_init);module_exit(dev_led_exit);MODULE_LICENSE("GPL");
平台驱动

led_drv.c

#include
#include
#include
//register_chrled#include
//class_create/ledice_create#include
//kmalloc#include
//copy_to_user/copy_from_user#include
//ioremap#include
//gpio_request#include
//s3c_gpio_cfgpin#include
//cdev_alloc#include
#include"led.h"static struct led_device *led_drv;static int led_open(struct inode *inode, struct file *file){ printk(KERN_INFO"%s()-%d\n", __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()-%d\n", __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()-%d\n", __func__, __LINE__); return 0;}static long led_ioctl(struct file *file, unsigned int cmd, unsigned long val){ printk(KERN_INFO"%s()-%d\n", __func__, __LINE__); printk(KERN_INFO"cmd=%d arg=%ld\n", 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_led\n"); return -ENOMEM; } /*1. 动态注冊/申请主设备*/ ret=alloc_chrdev_region(&led_drv->devno,0,1,"dev_module"); if (ret < 0) { printk(KERN_ERR "unable to get major\n"); 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_class\n"); 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_device\n"); 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 __init led_init(void){ platform_driver_register(&s5pv210_led_driver); return 0;}static void __exit led_exit(void){ platform_driver_unregister(&s5pv210_led_driver);}module_init(led_init);module_exit(led_exit);MODULE_LICENSE("GPL");

測试程序:

#include 
#include
#include
#include
#include
#include
#include
#include
#include "led.h"/*** ./led_test on num 点亮LED1/2** ./led_test off num 熄灭LED1/2*/int main(int argc, char *argv[]){ if (argc != 3) printf("input:< %s on led_num >or< %s off led_num>\n",argv[0],argv[0]); 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); } if(strcmp(argv[1],"on")==0){ cmd=LED_ON; }else if(strcmp(argv[1],"off")==0){ cmd=LED_OFF; }else{ printf("err input!\n"); } val = atoi(argv[2]); if(ioctl(fd,cmd,val)<0){ perror("ioctl failed!\n"); exit(1); } close(fd); return 0;}
Makefile

ifeq ($(KERNELRELEASE),)	KERNELDIR =/home/farsight/work/kernel/linux-3.0.8	PWD =$(shell pwd)modules:	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules	arm-none-linux-gnueabi-gcc led_test.c -o led_test	cp led_drv.ko dev_led.ko led_test /opt/filesystem/s5pv210modules_install:	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_installclean:	rm -rf *.so *.o *.ko *test  .tmp_versions *.mod.c *.order *.symvers else	obj-m :=led_drv.o dev_led.oendif

转载于:https://www.cnblogs.com/llguanli/p/8436663.html

你可能感兴趣的文章
一、 Python概述、变量
查看>>
sklearn中的损失函数
查看>>
PHP字符串相关函数
查看>>
importlib
查看>>
那么问题来了,什么才是正确的?我们就是为问题而生的
查看>>
string StartsWith 方法 Https
查看>>
finally不管有没有错都会运行 finally 块用于清除 try 块中分配的任何资源,以及运行任何即使在发生异常时也必须执行的代码...
查看>>
jmeter非GUI的运行命令
查看>>
波特率
查看>>
2016 Multi-University Training Contest 2
查看>>
xftp找不到匹配的outgoing encryption 算法 怎么解决
查看>>
【一周一算法】算法3:最常用的排序——快速排序
查看>>
四则运算实现
查看>>
JMV监控工具之JConsole
查看>>
iis 访问网站需要进行身份验证
查看>>
Project: Individual Project - Word frequency program
查看>>
python安装BeautifulSoup注意事项
查看>>
DEDE时间
查看>>
《神经网络和深度学习》系列文章七:实现我们的神经网络来分类数字(上)...
查看>>
java——线程池
查看>>