本文基于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. Nowcoder Hash Function ( 拓扑排序 && 线段树优化建图 )

    题目链接 题意 : 给出一个哈希表.其避免冲突的方法是线性探测再散列.现在问你给出的哈希表是否合法.如果合法则输出所有元素插入的顺序.如果有多解则输出字典序最小的那一个.如果不合法则输出 -1 分析 ...

  2. maven安装问题解决

    出现: The JAVA_HOME environment variable is not defined correctly This environment variable is needed ...

  3. 「HAOI2016」食物链

    题目链接 解题思路 简单的DAG上DP即可. 参考程序 #include <bits/stdc++.h> using namespace std; const int Maxn = 100 ...

  4. [VIJOS2055][SDOI2019]移动金币:DP+组合数学

    分析 显然可以转化为阶梯nim. 于是问题转化为了对于所有\(i \in [0,n-m]\),求长度为\(\lfloor\frac{m+1}{2}\rfloor\),和为\(i\),异或和非\(0\) ...

  5. echarts 有关饼形图和map的使用技巧1(饼图)

    http://blog.csdn.net/yhn1121/article/details/52041742 先上个链接,百度无意间搜到的,写得比我全面,可以直接飞去看它: 之前写网页用过echarts ...

  6. Android学习_7/24

    一.           活动的生命周期 1.        活动状态 运行:位于返回栈栈顶 暂停:不在栈顶,但仍可见 停止:不在栈顶,完全不可见 销毁:从栈中移除 2.        活动的生存期 ...

  7. TCP 之 TCP首部

    TCP首部图 TCP首部说明 源端口,目的端口 用于寻找发送端和接收端应用进程.(源IP,源端口,目的IP,目的端口) 四元组确定唯一一个TCP连接:(IP,端口)也称为一个插口(socket): 序 ...

  8. Python 抓取数据存储到Mysql中

    # -*- coding: utf-8 -*- import os,sys import requests import bs4 import pymysql#import MySQLdb #连接MY ...

  9. RF变量

    变量作用域 变量类型 变量作用域 case中的变量 case内部 userkeyword中的变量 userkeyword内部 文件型suite里的变量 文件suite内部,其下case均可使用 目录型 ...

  10. C语言转义字符表和ASCII码表

    主要参考 http://www.51hei.com/mcu/4342.html 以及 https://www.cnblogs.com/jason207489550/p/6663444.html