转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/38515205

之前一直在考虑该不该写这篇,由于我之前在博客里有写过LED的驱动,可是没有具体的解说。后来本着叫大家都能看懂驱动的想法,我还是决定要写一下。我想通过LED的驱动,让不了解驱动的小伙伴。可以有一个感性的认识。

一.代码

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/device.h>
#include <mach/gpio.h> static struct class *wvm_led_class;
static int major; volatile unsigned long *gpbcon = NULL;
volatile unsigned long *gpbdat = NULL; static int wvm_led_drv_open(struct inode *inode, struct file *file)
{
/*
* LED1,LED2,LED4相应GPB5、GPB6、GPB7、GPB8
*/
/* 配置GPB5,6,7,8为输出 */
*gpbcon &= ~((0x3<<(5*2)) | (0x3<<(6*2)) | (0x3<<(7*2)) | (0x3<<(8*2)));
*gpbcon |= ((0x1<<(5*2)) | (0x1<<(6*2)) | (0x1<<(7*2)) | (0x1<<(8*2)));
return 0;
} static int wvm_led_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
int val,ret; ret=copy_from_user(&val, buf, count); // copy_to_user();
if (ret)
return -EAGAIN; if (val == 1)
{
// 点灯
*gpbdat &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
}
else
{
// 灭灯
*gpbdat |= (1<<5) | (1<<6) | (1<<7) | (1<<8);
} return 0;
} static struct file_operations wvm_led_drv_fops = {
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自己主动创建的__this_module变量 */
.open = wvm_led_drv_open,
.write = wvm_led_drv_write,
}; static int wvm_led_drv_init(void) //入口函数(做初始化,创建设备等工作)
{
major = register_chrdev(0, "wvm_led_drv", &wvm_led_drv_fops); // 注冊, 告诉内核
if(major < 0)
{
printk( " wvm_led_drv register falid!/n");
return major;
} wvm_led_class = class_create(THIS_MODULE, "wvm_led");
if(IS_ERR(wvm_led_class))
{
printk( " wvm_led_drv register class falid!/n");
return -1;
} device_create(wvm_led_class, NULL, MKDEV(major, 0), NULL, "led"); /* /dev/led */ gpbcon = (volatile unsigned long *)ioremap(0x56000010, 16);
gpbdat = gpbcon + 1; return 0;
} static void wvm_led_drv_exit(void) //出口函数(做卸载和销毁工作)
{
unregister_chrdev(major, "wvm_led_drv"); // 卸载
device_destroy(wvm_led_class, MKDEV(major, 0));
class_destroy(wvm_led_class);
iounmap(gpbcon);
} module_init(wvm_led_drv_init); //定义入口函数
module_exit(wvm_led_drv_exit); //定义出口函数 MODULE_LICENSE("GPL");

二.驱动结构

正所谓麻雀虽小五脏俱全,它包含了一个驱动的基本功能。以下我写一个类似于模板的东西给大家。

//头文件

...

//定义一些变量和结构体等

...

//各种操作函数

xx_open()

{

.....

}

xx_close()

{

.....

}

xx_ioctl()

{

.....

}

...

//file_operations结构体

static struct file_operations XXX_drv_fops = {

        .owner   =  THIS_MODULE,    /* 这是一个宏。推向编译模块时自己主动创建的__this_module变量 */

        .open     =  XXX_open,           //后面的名字要与操作函数一致

        .close    =  XXX_close,

.ioctl  
    =  XXX_ioctl, 

  

};

//入口函数

static int XXX_init(void)

{

主要做创建设备等初始化工作。參照前面驱动(要推断返回值)。

}

//出口函数

static voidXXX_exit(void)

{

主要卸载创建的设备。做一些清理工作。參考前面的驱动去写

}

//入口、出口、证书的声明

module_init(XXX_init);

module_exit(XXX_exit);

MODULE_LICENSE("GPL");

三.应用測试

应用就是简单的測试一下开灯和关灯

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h> /* led_test on 开灯
* led_test off 关灯
*/
int main(int argc, char **argv)
{
int fd;
int val = 1;
fd = open("/dev/led", O_RDWR);
if (fd < 0)
{
printf("can't open!\n");
}
if (argc != 2)
{
printf("Usage :\n");
printf("%s <on|off>\n", argv[0]);
return 0;
} if (strcmp(argv[1], "on") == 0)
{
val = 1;
}
else
{
val = 0;
} write(fd, &val, 4);
return 0;
}

看到这也许有的小伙伴们已经买白了驱动怎么写,可是灯怎么亮的呢?

应用程序:write()----->驱动程序:write()

细心的小伙伴已经注意到驱动中的write()中有ret=copy_from_user(&val, buf, count);

然后就能够開始运行亮灯和灭灯了

两步搞定亮灭灯:

因为一个引脚可能同意有不同的功能,所以引脚的寄存器分为两类。一类为控制寄存器。一类数据寄存器

要操作某个引脚先设置控制寄存器(配置为某种功能)。然后设置数据寄存器(实现功能)

*gpbcon &= ~((0x3<<(5*2)) | (0x3<<(6*2)) | (0x3<<(7*2)) | (0x3<<(8*2)));  //清零

    *gpbcon |= ((0x1<<(5*2)) | (0x1<<(6*2)) | (0x1<<(7*2)) | (0x1<<(8*2)));     //配置为输出引脚

// 点灯

        *gpbdat &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));

// 灭灯

        *gpbdat |= (1<<5) | (1<<6) | (1<<7) | (1<<8);

这里面要注意一点,在曾经单片机敲代码的的时候我们能够直接操作物理地址,可是如今驱动要操作虚拟地址。

所以我们要做一个映射

gpbcon = (volatile unsigned long *)ioremap(0x56000010, 16);  //物理地址0x56000010 ,映射长度16字节

gpbdat = gpbcon + 1;

远程视频监控之驱动篇(LED)的更多相关文章

  1. 远程视频监控之应用篇(mjpg-streamer)

    这篇文章将主要结合源码介绍mjpg-streamer,使小伙伴们了解视频监控的实现. 一.移植 tar xvf mjpg-streamer-r63.tar.gz cd mjpg-streamer-r6 ...

  2. Python远程视频监控

    Python远程视频监控程序   老板由于事务繁忙无法经常亲临教研室,于是让我搞个监控系统,让他在办公室就能看到教研室来了多少人.o(>﹏<)o||| 最初我的想法是直接去网上下个软件,可 ...

  3. 如何利用SimpleNVR建立全天候远程视频监控系统

    随着社会经济的发展,5G.AI.云计算.大数据.物联网等新兴技术迭代更新的驱动下,传统的安防监控早已无法满足我们的需求.那么我们如何建立全天候远程视频监控系统来替代传统监控呢?如何进一步优化城市管理. ...

  4. H.264远程视频监控系统

    由usb摄像头驱动,h264编码库,采集read_video,传输,客户端显示组成 读取摄像头数据缓冲区是否有帧数据收到,有数据收到就读取数据并进行H264编码,把数据发送到socket发送到客户端. ...

  5. 基于Android的远程视频监控系统(含源码)

    基本过程是android作为socket客户端将采集到的每一帧图像数据发送出去,PC作为服务器接收并显示每一帧图像实现远程监控.图片如下(后来PC端加了个拍照功能)... (PS.刚学android和 ...

  6. Flex 远程视频监控观看端新版

    第一个版本号仅仅做了预览这一块 http://blog.csdn.net/songanling/article/details/38306037,后面老板看了认为色调太暗.看得不舒服,然后就開始又一次 ...

  7. 嵌入式应用开发第四阶段-基于rk3399的视频监控系统

    一.需求分析 伴随着嵌入式技术.图像处理技术和无线网络传输技术的发展,传统模拟视频监控系统和基于PC的远程视频监控系统由于自身的不足,已经无法满足现代社会应用中不断涌现出来的新需求,于是基于嵌入式技术 ...

  8. C# 视频监控系列:学习地址汇总

    原文地址:http://www.cnblogs.com/over140/archive/2009/04/07/1429308.html 前言 对于视频监控系统大家应该是不陌生的,实施的路况信息.地铁. ...

  9. 【树莓派+.NET MF打造视频监控智能车】遥控篇

    树莓派是最近比较火热的开源硬件,其设备只有信用卡大小,运行着Linux系统,专为学生编程教育而设计.我十多年的技术路线基本以学习微软的技术为主,中间也曾试图学习过linux,但是相对陡峭的学习曲线,只 ...

随机推荐

  1. 二重积分的计算 —— 交换积分顺序(exchange the order of integration)

    交换积分顺序的诀窍在数形结合: 1. 几句顺口溜 后积先定限,限内穿条线,先交下限写,后交上限见 先积 x,画横线(平行于 x 轴),右减左: 先积 y,画竖线(平行于 y 轴),上减下: 2. 简单 ...

  2. 淘宝CDN系统架构

         存储与架构分论坛上,淘宝网技术委员会主席,淘宝网核心工程师章文嵩向我们详细介绍了淘宝网图片处理与存储系统的架构.章文嵩博士的演 讲日程包括了 淘宝的整个系统架构.淘宝图片存储系统架构,淘宝网 ...

  3. POJ3087 Shuffle'm Up

    题目: 现有字符串s1.s2.s12,其中s1.s2的长度为len,s12的长度为2*len. 是否可以通过一些操作使s1和s2转换合并成s12? 变换的操作规则如下: 假设s1=11111,s2=0 ...

  4. HDU2080 夹角有多大2

    2019-05-17 15:00:09 加油加油,fightting !!! 这道题不知道acos()函数,acos()返回的是弧度,转化成度数要 / PI * 180 也没有想到通过向量 但是想到了 ...

  5. 如何卸载Win10自带Xbox、人脉、天气等应用?

    Win10中的Modern应用一般可在右键菜单中进行卸载,不过某些自带的Modern应用,比如Xbox.天气.人脉.照片等应用是无法在右键菜单中进行卸载的.如果你有卸载这些应用的需求,可参考下面的方法 ...

  6. android 学习记录-----------android 活动 意图 碎片

    将此篇博客作为记录android项目开发过程中的学习记录

  7. WebService 服务接口

    天气预报Web服务,数据来源于中国气象局Endpoint :http://www.webxml.com.cn/WebServices/WeatherWebService.asmxDisco :http ...

  8. 使用PyQT编写界面程序

    使用PyQT比QT好在,可以随时监测函数正确性,省去编译时间 ! 这是个不小的节省. 1. PyQt: 打开对话框 msgbox = QtGui.QMessageBox(self)# 我的语句是 ms ...

  9. 基于MapReduce的贝叶斯网络算法研究参考文献

    原文链接(系列):http://blog.csdn.net/XuanZuoNuo/article/details/10472219 论文: 加速贝叶斯网络:Accelerating Bayesian ...

  10. 图片放大不失真软件PhotoZoom如何使用?

    PhotoZoom可以将我们一些过于像素低的照片可以无失真放大,那么PhotoZoom是如何实现无失真照片放大的呢? 以上图像中的编号表示每个步骤应操作的位置. 单击“打开”,并选择您想调整大小的图像 ...