第四季-专题11-LED驱动程序设计

专题11-LED驱动程序设计

第1课-字符设备控制

  1. 设备控制理论

(1)作用

大部分驱动程序除了需要提供读写设备的能力外,还需要具备控制设备的能力。比如: 改变波特率。

(2)应用程序接口

在用户空间,使用ioctl系统调用来控制设备,原型如下:

int ioctl(int fd,unsigned long cmd,...)

fd: 要控制的设备文件描述符

cmd: 发送给设备的控制命令

…: 第3个参数是可选的参数,存在与否是依赖于控制命令(第2 个参数)。

(3)设备驱动方法

当应用程序使用ioctl系统调用时,驱动程序将由如下函数来响应:

1: 2.6.36 之前的内核

long (*ioctl) (struct inode* node ,struct file* filp, unsigned int cmd,unsigned long arg)

2:2.6.36之后的内核

long (*unlocked_ioctl) (struct file *filp, unsigned int cmd, unsigned long arg)

参数cmd: 通过应用函数ioctl传递下来的命令

  1. 设备控制实现

(1)       定义命令

命令从其实质而言就是一个整数, 但为了让这个整数具备更好的可读性,我们通常会把这个整数分为几个段:类型(8位),序号,参数传送方向,参数长度。

Type(类型/幻数): 表明这是属于哪个设备的命令。

Number(序号),用来区分同一设备的不同命令

Direction:参数传送的方向,可能的值是_IOC_NONE(没有数据传输), _IOC_READ, _IOC_WRITE(向设备写入参数)

Size: 参数长度

Linux系统提供了下面的宏来帮助定义命令:

_IO(type,nr):不带参数的命令

_IOR(type,nr,datatype):从设备中读参数的命令

_IOW(type,nr,datatype):向设备写入参数的命令

例:

#define MEM_MAGIC ‘m’ //定义幻数

#define MEM_SET _IOW(MEM_MAGIC, 0, int)

(2)       实现操作

unlocked_ioctl函数的实现通常是根据命令执行的一个switch语句。但是,当命令号不能匹配任何一个设备所支持的命令时,返回-EINVAL.

编程模型:

Switch cmd

Case 命令A:

//执行A对应的操作

Case 命令B:

//执行B对应的操作

Default:

// return -EINVAL

  1. 自己动手写驱动

Led.c

#include <linux/module.h>

#include <linux/init.h>

#include <linux/cdev.h>

#include <linux/fs.h>

#include <linux/io.h>

#include <mach/gpio-bank-k.h>

#include "led.h"

#define LEDCON 0x7f008800

#define LEDDAT 0x7f008808

unsigned int *led_config;

unsigned int *led_data;

struct cdev cdev;

dev_t devno;

int led_open(struct inode *node, struct file *filp)

{

led_config = ioremap(LEDCON,4);

writel(0x11110000,led_config);

led_data = ioremap(LEDDAT,4);

return 0;

}

long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

{

switch (cmd)

{

case LED_ON:

writel(0x00,led_data);

return 0;

case LED_OFF:

writel(0xff,led_data);

return 0;

default:

return -EINVAL;

}

}

static struct file_operations led_fops =

{

.open = led_open,

.unlocked_ioctl = led_ioctl,

};

static int led_init()

{

cdev_init(&cdev,&led_fops);

alloc_chrdev_region(&devno, 0 , 1 , "myled");

cdev_add(&cdev, devno, 1);

return 0;

}

static void led_exit()

{

cdev_del(&cdev);

unregister_chrdev_region(devno,1);

}

module_init(led_init);

module_exit(led_exit);

led_app.c

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <sys/ioctl.h>

#include "led.h"

int main(int argc, char *argv[])

{

int fd;

int cmd;

if (argc <2 )

{

printf("please enter the second para!\n");

return 0;

}

cmd = atoi(argv[1]);

fd = open("/dev/myled",O_RDWR);

if (cmd == 1)

ioctl(fd,LED_ON);

else

ioctl(fd,LED_OFF);

return 0;

}

原文地址:https://www.cnblogs.com/free-1122/p/10994938.html

时间: 2024-11-13 04:15:46

第四季-专题11-LED驱动程序设计的相关文章

专题11 LED驱动程序设计

一.理论分析1.现实生活中,对一个设备除了能够读写之外,我们还希望能够对设备进行控制,比如说LED的亮灭,电机的转动等.2.一般希望能从应用程序传递命令给内核从而使得能够调用控制函数实现不同的控制.3.在用户空间,使用ioctl系统调用来控制设备:(应用程序接口)int ioctl(int fd,unsigned long cmd,...):4.重点是第二个参数cmd,他实质上就是一个整数.分成几块构成.5.在内核空间,相应的设备函数应该是(设备驱动方法)cmd是通过应用程序传递进来的.二.定义

第四季-专题15-网卡驱动程序设计

专题15-网卡驱动程序设计 第1课-网卡驱动架构分析 l  Linux网络子系统 l  系统调用接口层:为应用程序提供访问网络子系统的统一方法. l  协议无关层:提供通用的方法来使用传输层协议. l  协议栈的实现:实现具体的网络协议 l  设备无关层:协议与设备驱动之前通信的通用接口 l  设备驱动程序 重要数据结构 在Linux内核中,每个网卡都由一个net_device结构来描述,其中的一些重要成员有: l  char name[IFNAMSIZ],设备名,如:eth%d l  unsi

第四季-专题14-串口驱动程序设计

专题14-串口驱动程序设计 第1课-tty驱动架构 TTY概念解析 在Linux系统中,终端是一类字符型设备,它包括多种类型,通常使用tty来简称各种类型的终端设备. l  串口终端(/dev/ttyS*) 串口终端是使用计算机串口连接的终端设备.Linux 把每个串行端口都看作是一个字符设备.这些串行 端口所对应的设备名称是/dev/ttySAC0; /dev/ttySAC1…… l  控制台终端(/dev/console) 在Linux系统中,计算机的输出设备通常被称为控制台终端(Conso

led驱动程序设计

LED的驱动程序很简单,按照张字符型设备驱动设计方法顺下来即可实现,这里主要讲几个注意事项. 一.在linux系统中,操作硬件不能够使用物理地址,一定要用虚拟地址.将物理地址转化为虚拟地址的函数如下: #define    ioremap(cookie,size) 其中cookie为要转化的物理地址,size为转化空间的大小,单位为字节.返回值为转化后的虚拟地址. 二.在执行程序时我们需要顺带输入参数进去,但是是以字符串的形式输入的,不方便操控.所以用atoi函数将字符串转化为整数,函数原型如下

[国嵌攻略][117][LED驱动程序设计]

LED程序设计 1.编写内核模块 2.搭建字符驱动框架 3.实现设备方法 头文件 <linux/io.h> writel() leddev.h //设备命令 #define LED_MAGIC 'L' //LED幻数 #define LED_ON _IO(LED_MAGIC, 0) //打开LED #define LED_OFF _IO(LED_MAGIC, 1) //关闭LED leddev.c /***********************************************

简单的led驱动程序设计

基于ok6410: led驱动程序: vim led.c #include<linux/kernel.h>#include<linux/module.h>#include<linux/init.h>#include<linux/io.h>#include<linux/fs.h>#include<linux/cdev.h>#include"led.h"#include<mach/gpio-bank-k.h>

第四季-专题18-FLASH驱动程序设计

专题18-FLASH驱动程序设计 第1课-块设备驱动系统架构 块设备快速体验 块设备是指只能以块为单位进行访问的设备,块大小一般是512个字节的整数倍.常见的块设备包括硬件,SD卡,光盘等. l  insmod simple-blk.ko l  ls /dev/simp_blkdev0 l  mkfs.ext3 /dev/simp_blk0 l  mkdir –p /mnt/blk l  mount /dev/simp_blk0 /mnt/blk l  cp /etc/init.d/* /mnt

第四季-专题20-SPI驱动程序设计

专题20-SPI驱动程序设计 第1课-SPI总线介绍 总线结构 SPI(Serial Peripheral Interface)串行外设接口,是一种高速的,全双工,同步的通信总线.采用主从模式(Master Slave)架构,支持多个slave,一般仅支持单Master. SPI接口共有4根信号线,分别是:设备选择线(SS).时钟线(SCK).串行输出数据线(MOSI).串行输入数据线(MISO) 数据传输过程 主节点通过MOSI 线输出数据,从节点在SIMO 处从主节点读取数据.同时,也在通过

第四季-专题19-I2C驱动程序设计

专题19-I2C驱动程序设计 第1课-I2C总线介绍 I2C硬件结构 (1)     电气特性 I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备. I2C总线只有两根双向信号线.SDA: Serial Data Line-数据线SCL :Serial Clock-时钟线. (2)     总线寻址 I2C总线协议规定:从设备采用7位的地址.D7-D1:从设备地址.D0位:数据传送方向位,为“0”时表示主设备向从