实现功能,点亮LED,参考了网上部分代码。
1.在目录/src/kernel/drivers/下面建立一个文件夹testLed,并添加三个文件Makefile、mytestled.c、Kconfig。
Kconfig内容如下,后期编译时可以用make menuconfig命令,然后在Device Drivers --->一栏里面选择将该模块编译进去
config MYTESTLED tristate "My test led driver" help Test led driver
MakeFile内容如下:
obj-$(CONFIG_MYTESTLED) +=mytestled.o
mytestled.c内容如下:
#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/kernel.h> /* printk() */ #include <linux/slab.h> /* kmalloc() */ #include <linux/fs.h> /* everything... */ #include <linux/errno.h> /* error codes */ #include <linux/types.h> /* size_t */ #include <linux/mm.h> #include <linux/kdev_t.h> #include <linux/cdev.h> #include <linux/delay.h> #include <linux/device.h> #include <asm/io.h> #include <asm/uaccess.h> #include <linux/gpio.h> static int simple_major = 199; #define LED_ON 0x4800 #define LED_GPIO 258 #define GPIO_LOW 0 #define GPIO_HIGH 1 //LED闪烁1次 void led_on(void) { printk("lesStart.....\n"); gpio_set_value(LED_GPIO, GPIO_LOW); mdelay(1000); gpio_set_value(LED_GPIO, GPIO_HIGH); mdelay(1000); } /* * Open the device; in fact, there's nothing to do here. */ int simple_led_open(struct inode *inode, struct file *filp) { return 0; } ssize_t simple_read(struct file *file, char __user *buff, size_t count, loff_t *offp) { //在adb shell里面执行:cat /dev/testLed2 则会触发该函数 //led_on(); return 0; } ssize_t simple_write(struct file *file, const char __user *buff, size_t count, loff_t *offp) { return 0; } /** * 内核低于2.6.36 */ static int simple_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { case LED_ON: { led_on(); break; } default: { break; } } return 0; } /** * 内核高于2.6.36 */ static long simple_ioctl_new(struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { case LED_ON: { led_on(); break; } default: { break; } } return 0; } static int simple_release(struct inode *node, struct file *file) { return 0; } /* * Set up the cdev structure for a device. */ static void simple_setup_cdev(struct cdev *dev, int minor, struct file_operations *fops) { int err, devno = MKDEV(simple_major, minor); cdev_init(dev, fops); dev->owner = THIS_MODULE; dev->ops = fops; //第三个参数为设备个数 err = cdev_add(dev, devno, 1); /* Fail gracefully if need be */ if (err) printk (KERN_NOTICE "Error %d adding simple%d", err, minor); } /* * Our various sub-devices. */ /* Device 0 uses remap_pfn_range */ static struct file_operations simple_remap_ops = { .owner = THIS_MODULE, .open = simple_led_open, .release = simple_release, .read = simple_read, .write = simple_write, // 内核低于2.6.36则为.ioctl // .ioctl = simple_ioctl, .compat_ioctl = simple_ioctl_new }; /* * We export two simple devices. There's no need for us to maintain any * special housekeeping info, so we just deal with raw cdevs. */ static struct cdev SimpleDevs; /* * Module housekeeping. */ static struct class *my_class; static int simple_init(void) { int result; //根据主设备号和次设备号创建dev_t dev_t dev = MKDEV(simple_major, 0); if (simple_major) { //如果指定了具体的主设备号,则去注册,第二个参数表示注册的此设备数量,这里只有一个led,第三个参数为设备名字/proc/devices/testLed result = register_chrdev_region(dev, 1, "testLed"); } else { //如果没有指定具体的主设备号,则自动分配。第二个参数一般为0(次设备号的基准,从第几个次设备号开始分配),第三个参数表示注册的此设备数量 result = alloc_chrdev_region(&dev, 0, 1, "testLed"); //获取到自动分配所得到的主设备号 simple_major = MAJOR(dev); } if (result < 0) { //获取设备号失败 printk(KERN_WARNING "simple: unable to get major %d\n", simple_major); return result; } if (simple_major == 0) { simple_major = result; } simple_setup_cdev(&SimpleDevs, 0, &simple_remap_ops); printk("simple device installed, with major %d\n", simple_major); my_class = class_create(THIS_MODULE, "testLed"); //创建/dev/testLed2 device_create(my_class, NULL, MKDEV(simple_major, 0), NULL, "testLed2"); return 0; } static void simple_cleanup(void) { cdev_del(&SimpleDevs); unregister_chrdev_region(MKDEV(simple_major, 0), 1); device_destroy(my_class, MKDEV(simple_major, 0)); printk("simple device uninstalled\n"); } module_init( simple_init); module_exit( simple_cleanup);
2.在文件src/kernel/arch/arm/configs/firefly_defconfig最后增加下面一行,这样就无需用make menuconfig进行配置了
CONFIG_MYTESTLED=y
3.在文件src/kernel/drivers/Kconfig 最后增加下面一行
source "drivers/testLed/Kconfig"
4.在文件src/kernel/drivers/Makefile最后增加下面一行
obj-y += testLed/
5.重新编译kernel 即可
相关推荐
TQ2440开发板按键点亮LED驱动开发详解 很好,很强大,代码都有解释。
S3C2440开发板上实现按键点亮LED驱动开发的详细过程
第一节:基于C#使用开发板点亮LED灯实验
s3c2440开发板点亮一个LED程序的步骤,对于初学者的我有很大的帮助
基于imx6q-c开发板的led驱动程序,解压之后将文件放在misc 目下。亲测,可用。
资源是S3C6410开发板的LED设备驱动的测试代码,其中,mini6410_leds.c是S3C6410的linux系统设备驱动中的LED的驱动代码,led_test.c是LED驱动的测试代码。
汇编点亮stm32的nucleo的开发板的LD2的LED,亲自编写调试测试通过
TX-1C单片机开发板的D12驱动开发包,可以参考做单片机的USB开发。
。。。
。。。
OpenHarmony大师兄开发板的外设驱动开发说明,Python外设驱动原理及实验,GPIO驱动原理及实验,GPIO 即:General-Purpose Input/Output,通用型输入输出•在硬件设备上,GPIO通常表现为引脚(Pin)
GEC6818开发板,使用字符设备驱动点亮LED灯 创建字符设备驱动模型: 1.定义一个struct cdev 2.给cdev申请设备号 3.给cdev创建一个file_operations(文件操作集) 4.初始化cdev 5.将cdev加入内核 6.创建class 7.创建...
mini2440开发板的led测试程序。汇编
嵌入式开发板led点灯,基于6818开发板,包含源代码
基于MSP430F5529开发板——LED呼吸灯
附件内容为s3c2440开发板led灯驱动程序。 根据图文演示可清楚驱动程序的结构以及编写过程,图中亦标明相关头文件的作用,适合驱动初学者学习。
linux led驱动,自己学习时 感觉主要是makefile不会 导致很多文件找不到 这个事可以的 在自己的GT2440开发板验证通过的
在android开发板添加led驱动模块,并通过NDK工程生成应用层软件测试。
新唐n76e003单片机点亮LED,跟stm有点像, 里面我只弄了两种写法,我也是在学习中