lLinux驱动学习之编写一个简单的led驱动
2018-03-31 22:11
495 查看
做一个简单的流水灯程序是写单片机或者是Linux嵌入式驱动中最简单最基础的东西了。
本人自学单片机,从事Linux网络开发,现在想转做嵌入式驱动方向,故从现在开始学习更新博客,记录自己的学习内容也当是一个学习笔记和大家一起分享。有什么不正确的地方希望大家给予留言。
开始:
首先要在自己的Linux源码中创建自己的模块文件。我使用的是Linux2.6.23版本。
在drivers下创建自己的文件名为myled。
然后创建myleds.c文件,内容如下:
程序是最基本的框架程序,没有什么难度,只是对于刚开始学时有些难度,主要是对源码的不熟悉,相信随着不断的学习是可以越来越熟练的。
以下是Makefile和Kconfig的设置,很多书上都是有说的
在myleds目录下添加Makefile和Kconfig这两个文件,
这是Kconfig
还有Makefile
就是这么简单的一句
需要在上层目录的drivers目录下修改Makefile和Kconfig
在Makefile中添加:obj-$(CONFIG_TEST_SUPPORT) += myled/
在Kconfig中添加:source “drivers/myled/Kconfig”
然后编译内核模块:使用make modules命令;
在Linux源码的第一级目录下 make menuconfig设置myled模块为编译模块禁止编译进内核。然后使用make modules
在myleds目录下会生成myleds.ko文件。
将文件下载到开发板。
先使用mknod 文件目录 模块类型 主设备号 此设备号, 添加设备
mknod /dev/myled c 253 1 这个设备号是个前面的cdev_init()使用的设备号一致。
使用insmod myleds.ko加载模块,lsmod myleds 查看模块,rmmod myleds卸载模块,modprode myleds是否加载。
以下是应用程序代码:
有点晚了想睡觉,等明天起来再补充一个对相关函数的理解和我在学习中遇到的一些困难
对于如何搭建开发环境和编译内核很多书上都有很详细的说明。在这里就不赘述了。
下一步将和大家一起学习makefile的相关语法,机器汇编指令。
本人自学单片机,从事Linux网络开发,现在想转做嵌入式驱动方向,故从现在开始学习更新博客,记录自己的学习内容也当是一个学习笔记和大家一起分享。有什么不正确的地方希望大家给予留言。
开始:
首先要在自己的Linux源码中创建自己的模块文件。我使用的是Linux2.6.23版本。
在drivers下创建自己的文件名为myled。
然后创建myleds.c文件,内容如下:
/*开饭版采用的是友善之臂的s3c2440*/ #include <linux/fs.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/io.h> #include <linux/types.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/string.h> #define BASEADDR 0x56000010 #define LED_ON 0 #define LED_OFF 1 #define DEV_NAME "myled" char *memaddr; volatile unsigned long *gpbcon, *gpbdat, *gpbhup; static int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long pin); static struct file_operations dev_fops = { .owner = THIS_MODULE, .ioctl = led_ioctl, }; static struct __myled_tag__ { dev_t devno; struct cdev cdev; } myled_t; static int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long pin) { switch (cmd) { case LED_ON: *gpbdat &= ~(1 << pin); break; case LED_OFF: *gpbdat |= 1 << pin; break; } return 1; } //进行地址映射 static void dev_mem_init() { memaddr = ioremap(BASEADDR, 0x0c); gpbcon = (unsigned long *)memaddr; gpbdat = (unsigned long *)(memaddr + 0x04); gpbhup = (unsigned long *)(memaddr + 0x08); } static void set_led_register() { *gpbcon |= 0x55 << 10; //设置寄存器的管脚为output模式01. } static int __init dev_init(void) { myled_t.devno = MKDEV(253, 1); dev_mem_init(); cdev_init(&myled_t.cdev, &dev_fops); myled_t.cdev.owner = THIS_MODULE; if (register_chrdev_region(myled_t.devno, 1, DEV_NAME) != 0) { alloc_chrdev_region(&myled_t.devno, 1, 1, DEV_NAME); } cdev_add(&myled_t.cdev, myled_t.devno, 1); set_led_register(); printk("myled install!\n"); printk("major; %d, minor: %d\n", MAJOR(myled_t.devno), MINOR(myled_t.devno)); return 0; } static void __exit dev_exit(void) { unregister_chrdev_region(myled_t.devno, 1); iounmap((void *)memaddr); cdev_del(&myled_t.cdev); printk("myled remove!\n"); }
程序是最基本的框架程序,没有什么难度,只是对于刚开始学时有些难度,主要是对源码的不熟悉,相信随着不断的学习是可以越来越熟练的。
以下是Makefile和Kconfig的设置,很多书上都是有说的
在myleds目录下添加Makefile和Kconfig这两个文件,
这是Kconfig
还有Makefile
obj-$(CONFIG_TEST_USER) += myleds.o
就是这么简单的一句
需要在上层目录的drivers目录下修改Makefile和Kconfig
在Makefile中添加:obj-$(CONFIG_TEST_SUPPORT) += myled/
在Kconfig中添加:source “drivers/myled/Kconfig”
然后编译内核模块:使用make modules命令;
在Linux源码的第一级目录下 make menuconfig设置myled模块为编译模块禁止编译进内核。然后使用make modules
在myleds目录下会生成myleds.ko文件。
将文件下载到开发板。
先使用mknod 文件目录 模块类型 主设备号 此设备号, 添加设备
mknod /dev/myled c 253 1 这个设备号是个前面的cdev_init()使用的设备号一致。
使用insmod myleds.ko加载模块,lsmod myleds 查看模块,rmmod myleds卸载模块,modprode myleds是否加载。
以下是应用程序代码:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char **argv) { int pin; int cmd; int fd; int i; /*打开/dev/leds 设备文件*/ fd = open("/dev/myled", O_RDWR); if (fd < 0) { perror("open device myled"); exit(1); } /*通过系统调用 ioctl 和输入的参数控制 led*/ while (1) { for (i = 5; i < 9; i++) { ioctl(fd, 0, i); usleep(500000); } for (i = 5; i < 9; i++) ioctl(fd, 1, i); for (i = 8; i > 4; i--) { ioctl(fd, 0, i); usleep(500000); } for (i = 5; i < 9; i++) ioctl(f 9f40 d, 1, i); } /*关闭设备句柄*/ close(fd); return 0; }
有点晚了想睡觉,等明天起来再补充一个对相关函数的理解和我在学习中遇到的一些困难
对于如何搭建开发环境和编译内核很多书上都有很详细的说明。在这里就不赘述了。
下一步将和大家一起学习makefile的相关语法,机器汇编指令。
相关文章推荐
- Linux驱动学习(编写一个最简单的模块)
- 自己动手写最简单的Android驱动---LED驱动的编写
- ROS学习笔记十:用C++编写一个简单的服务和客户端
- Linux 字符设备驱动开发基础(一)—— 编写简单 LED 设备驱动
- 通过编写一个简单的漏洞扫描程序学习Python基本语句
- 基于arm的一个简单的led驱动
- unity 3D学习日记:创建一个小场景并编写简单C#移动脚本
- shell语法的简单学习以及编写一个简单的进度条
- 学习LSM(Linux security module)之二:编写并运行一个简单的demo
- 系统学习JavaWeb之三编写一个简单的Servlet应用程序
- 一个极简单的 块设备驱动 的编写
- 自己动手写最简单的Android驱动---LED驱动的编写
- 三. 学习Unix/Linux编程之事件驱动编程:编写一个视频游戏
- ROS学习--(十二)编写一个简单的发布器(publisher)
- linux字符驱动学习实践1(简单控制LED灯)
- Python学习 - 编写一个简单的web框架(一)
- 自己动手写最简单的Android驱动---LED驱动的编写【转】
- 学习笔记:创建一个简单字符设备驱动的过程
- 【Rebol 学习笔记】第一篇:编写一个简单的 CGI 程序
- Ubuntu 14.04上驱动开发环境配置,及最简单一个驱动编写。