本文基于icool210开发板,内核版本:linux2.6.35;

驱动代码:

(1)头文件:led.h

 #ifndef __LED_H__
#define __LED_H__ #define LED_MAGIC 'l'
#define LED_1_ON _IO(LED_MAGIC, 0)
#define LED_1_OFF _IO(LED_MAGIC, 1)
#define LED_2_ON _IO(LED_MAGIC, 3)
#define LED_2_OFF _IO(LED_MAGIC, 4)
#define LED_3_ON _IO(LED_MAGIC, 5)
#define LED_3_OFF _IO(LED_MAGIC, 6)
#define LED_4_ON _IO(LED_MAGIC, 7)
#define LED_4_OFF _IO(LED_MAGIC, 8)
#define LED_5_ON _IO(LED_MAGIC, 9)
#define LED_5_OFF _IO(LED_MAGIC, 10)
#define LED_6_ON _IO(LED_MAGIC, 11)
#define LED_6_OFF _IO(LED_MAGIC, 12) #endif

(2)代码文件:led.c

 #include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/io.h>
#include "led.h" #define GPBCON 0xE0200040
#define GPBDAT 0xE0200044
#define GPH0CON 0xE0200C00
#define GPH0DAT 0xE0200C04
unsigned int *led_gpb_config;
unsigned int *led_gpb_data;
unsigned int *led_gph0_config;
unsigned int *led_gph0_data; struct cdev led_dev;
dev_t devno; /****************************************************************************
** 函数名: led_open
** 功 能: led设备驱动的操作函数集的open函数
** 参 数: struct inode *pstInode
** struct file *pstFile
** 日 期: 2017年2月22日
** 作 者: Rookie
*****************************************************************************/
int led_open(struct inode *pstInode, struct file *pstFile)
{
unsigned int uiDataTemp; /*
** 配置LED对应的GPIO为Output
** LED1 -- GPB0 LED2 -- GPIO2
** LED3 -- GPB1 LED4 -- GPIO4
*/
led_gpb_config = ioremap(GPBCON, );
uiDataTemp = readl(led_gpb_config);
uiDataTemp &= 0xFFFF0000;
uiDataTemp |= 0x1111;
writel(uiDataTemp, led_gpb_config); /* LED5 -- GPH0_7 LED6 -- GPH0_5 */
led_gph0_config = ioremap(GPH0CON, );
uiDataTemp = readl(led_gph0_config);
uiDataTemp &= 0xF0FFFFF;
uiDataTemp |= 0x10100000;
writel(uiDataTemp, led_gph0_config); led_gpb_data = ioremap(GPBDAT, );
led_gph0_data = ioremap(GPH0DAT, ); return ;
} /****************************************************************************
** 函数名: led_ioctl
** 功 能: led设备驱动的操作函数集的ioctl函数
** 参 数: struct file *pstFile
** unsigned int uiCmd
** unsigned long ulArgc
** 日 期: 2017年2月22日
** 作 者: Rookie
*****************************************************************************/
long led_ioctl(struct file *pstFile, unsigned int uiCmd, unsigned long ulArgc)
{
unsigned int uiDataTemp; switch (uiCmd)
{
case (LED_1_ON):
uiDataTemp = readl(led_gpb_data);
uiDataTemp |= 0x1;
writel(uiDataTemp, led_gpb_data);
printk("led1--on\r\n");
break; case (LED_1_OFF):
uiDataTemp = readl(led_gpb_data);
uiDataTemp &= 0xFFFFFFFE;
writel(uiDataTemp, led_gpb_data);
printk("led1--off\r\n");
break; case (LED_2_ON):
uiDataTemp = readl(led_gpb_data);
uiDataTemp |= 0x4;
writel(uiDataTemp, led_gpb_data);
printk("led2--on\r\n");
break; case (LED_2_OFF):
uiDataTemp = readl(led_gpb_data);
uiDataTemp &= 0xFFFFFFFB;
writel(uiDataTemp, led_gpb_data);
printk("led2--off\r\n");
break; case (LED_3_ON):
uiDataTemp = readl(led_gpb_data);
uiDataTemp |= 0x2;
writel(uiDataTemp, led_gpb_data);
break; case (LED_3_OFF):
uiDataTemp = readl(led_gpb_data);
uiDataTemp &= 0xFFFFFFFD;
writel(uiDataTemp, led_gpb_data);
break; case (LED_4_ON):
uiDataTemp = readl(led_gpb_data);
uiDataTemp |= 0x8;
writel(uiDataTemp, led_gpb_data);
break; case (LED_4_OFF):
uiDataTemp = readl(led_gpb_data);
uiDataTemp &= 0xFFFFFFF7;
writel(uiDataTemp, led_gpb_data);
break; case (LED_5_ON):
uiDataTemp = readl(led_gph0_data);
uiDataTemp |= 0x80;
writel(uiDataTemp, led_gph0_data);
break; case (LED_5_OFF):
uiDataTemp = readl(led_gph0_data);
uiDataTemp &= 0xFFFFFF7F;
writel(uiDataTemp, led_gph0_data);
break; case (LED_6_ON):
uiDataTemp = readl(led_gph0_data);
uiDataTemp |= 0x20;
writel(uiDataTemp, led_gph0_data);
break; case (LED_6_OFF):
uiDataTemp = readl(led_gph0_data);
uiDataTemp &= 0xFFFFFFDF;
writel(uiDataTemp, led_gph0_data);
break; default:
return -EINVAL;
} return ;
} static struct file_operations led_ops =
{
.open = led_open,
.unlocked_ioctl = led_ioctl,
}; /****************************************************************************
** 函数名: led_init
** 功 能: led设备驱动初始化函数
** 参 数: void
** 日 期: 2017年2月22日
** 作 者: Rookie
*****************************************************************************/
static int __init led_init(void)
{
cdev_init(&led_dev, &led_ops); alloc_chrdev_region(&devno, , , "my_led");
cdev_add(&led_dev, devno, ); return ;
} /****************************************************************************
** 函数名: led_exit
** 功 能: led设备驱动退出函数
** 参 数: void
** 日 期: 2017年2月22日
** 作 者: Rookie
*****************************************************************************/
static void __exit led_exit(void)
{
cdev_del(&led_dev);
unregister_chrdev_region(devno, ); return;
} module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

(3)Makefile文件

 obj-m := led.o
KDIR := /root/wksp/icool210/linux2.6.35-icool210-v1.
all:
make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
clean:
rm -rf *.ko *.o *.order *symvers

(4)测试应用程序:app.c

 #include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "led.h" int main(int argc, const char *argv[])
{
int iFd;
int iLedNum;
int iLedStatus; if (argc < )
{
printf("Please Enter 3 Para!\r\n");
return -;
} iLedNum = atoi(argv[]);
iLedStatus = atoi(argv[]); iFd = open("/dev/my_led", O_RDWR); if ( == iLedNum)
{
if ( == iLedStatus)
{
ioctl( iFd, LED_1_ON);
}
else
{
ioctl( iFd, LED_1_OFF);
}
}
else if ( == iLedNum)
{
if ( == iLedStatus)
{
ioctl( iFd, LED_2_ON);
}
else
{
ioctl( iFd, LED_2_OFF);
}
}
else if ( == iLedNum)
{
if ( == iLedStatus)
{
ioctl( iFd, LED_3_ON);
}
else
{
ioctl( iFd, LED_3_OFF);
}
}
else if ( == iLedNum)
{
if ( == iLedStatus)
{
ioctl( iFd, LED_4_ON);
}
else
{
ioctl( iFd, LED_4_OFF);
}
}
else if ( == iLedNum)
{
if ( == iLedStatus)
{
ioctl( iFd, LED_5_ON);
}
else
{
ioctl( iFd, LED_5_OFF);
}
}
else if ( == iLedNum)
{
if ( == iLedStatus)
{
ioctl( iFd, LED_6_ON);
}
else
{
ioctl( iFd, LED_6_OFF);
}
} return ;
}

操作方法:

(1)编译 .ko 文件

在驱动代码路径直接执行 make

(2)编译 应用程序

arm-linux-gcc -static app.c -o app

(3)记载内核模块

insmod led.ko

(4)创建设备节点

mknod /dev/my_led c 251 0

(5) 执行应用程序

./app 1 1

【Linux 驱动】简单字符设备驱动架构(LED驱动)的更多相关文章

  1. 【转】深入浅出:Linux设备驱动之字符设备驱动

    深入浅出:Linux设备驱动之字符设备驱动 一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据 ...

  2. Linux驱动设计——字符设备驱动(一)

    Linux字符设别驱动结构 cdev结构体 struct cdev { struct kobject kobj; struct module *owner; const struct file_ope ...

  3. 【Linux-驱动】简单字符设备驱动结构和初始化

    (1)在编写简单字符设备驱动的时候,首先要申请一个设备结构struct cdev: struct cdev { struct kobject kobj; struct module *owner; / ...

  4. Linux 简单字符设备驱动程序 (自顶向下)

    第零章:扯扯淡 特此总结一下写的一个简单字符设备驱动程序的过程,我要强调一下“自顶向下”这个介绍方法,因为我觉得这样更容易让没有接触过设备驱动程序的童鞋更容易理解,“自顶向下”最初从<计算机网络 ...

  5. 【转】linux设备驱动程序之简单字符设备驱动

    原文网址:http://www.cnblogs.com/geneil/archive/2011/12/03/2272869.html 一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用 ...

  6. 手把手教Linux驱动3-之字符设备架构详解,有这篇就够了

    一.Linux设备分类 Linux系统为了管理方便,将设备分成三种基本类型: 字符设备 块设备 网络设备 字符设备: 字符(char)设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程 ...

  7. 深入浅出:Linux设备驱动之字符设备驱

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流 ...

  8. 【Linux驱动】字符设备驱动

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 1.字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面 ...

  9. linux设备驱动之字符设备驱动模型(1)

    一:字符设备驱动 在linux下面,应用层看到的一切皆为文件(名字)所有的设备都是文件,都可以调用open,read,write来操作,而在内核中每个中每个设备有唯一的对应一个设备号: APP   ( ...

随机推荐

  1. vs2017 2019 下载更新慢的解决方法

    国庆期间 下载的速度只有20多kb. 1.去掉网络适配器里面的 ip6勾选. 2.修改电脑的自动dns, 修改为1.1.1.1  , 修改为8.8.8.8  更快. 记得禁用再启用网络: dns为1. ...

  2. Eclipse中导入两个相同的工程

    问题描述:同时在Eclipse中导入两个相同的工程,会有 Some projects cannot be imported because they already exist in the work ...

  3. SpringBoot项目中,获取配置文件信息

    1.在配置文件中设置信息,格式如下 wechat: mpAppId: wxdf2b09f280e6e6e2 mpAppSecret: f924b2e9f140ac98f9cb5317a8951c71 ...

  4. Web大文件上传断点续传解决方案

    最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现. 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表 ...

  5. python之timeit模块

    timeit模块: timeit 模块定义了接受两个参数的 Timer 类.两个参数都是字符串. 第一个参数是你要计时的语句或者函数. 传递给 Timer 的第二个参数是为第一个参数语句构建环境的导入 ...

  6. BZOJ 4849 [NEERC2016]Mole Tunnels (模拟费用流)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4849 题解 其实也是模拟费用流,但是这道题和一般的题目不一样,这道题是在一个完全二叉树上 ...

  7. Max Sum Plus Plus(最大m字段和,优化)

    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description Now I t ...

  8. GC详解

    GC,即就是Java垃圾回收机制.目前主流的JVM(HotSpot)采用的是分代收集算法.与C++不同的是,Java采用的是类似于树形结构的可达性分析法来判断对象是否还存在引用.即:从gcroot开始 ...

  9. MyExcel 2.2.0 版本发布,支持公式导出

    MyExcel,是一个集导入.导出.加密Excel等多项功能的java工具包. 相关链接 MyExcel 的详细介绍:点击查看 MyExcel 的下载地址:点击下载

  10. spark MLlib 概念 3: 卡方分布(chi-squared distribution)

    数学定义[编辑] 若k个随机变量.--.是相互独立,符合标准正态分布的随机变量(数学期望为0.方差为1),则随机变量Z的平方和 被称为服从自由度为 k 的卡方分布,记作 Definition[edit ...