tiny4412字符设备的上层测试程序(底层驱动为/dev/leds)

leds

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>

#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>

#define DEVICE_NAME "led9"

static int led_gpios[] = {
EXYNOS4X12_GPM4(0),
EXYNOS4X12_GPM4(1),
EXYNOS4X12_GPM4(2),
EXYNOS4X12_GPM4(3),
};

#define LED_NUM ARRAY_SIZE(led_gpios)

static long tiny4412_leds_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
switch(cmd) {
case 0:
case 1:
if (arg > LED_NUM) {
return -EINVAL;
}

gpio_set_value(led_gpios[arg], !cmd);
//printk(DEVICE_NAME": %d %d\n", arg, cmd);
break;

default:
return -EINVAL;
}

return 0;
}

static struct file_operations tiny4412_led_dev_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = tiny4412_leds_ioctl,
};

static struct miscdevice tiny4412_led_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &tiny4412_led_dev_fops,
};

static int __init tiny4412_led_dev_init(void) {
int ret;
int i;

for (i = 0; i < LED_NUM; i++) {
ret = gpio_request(led_gpios[i], "LED");
if (ret) {
printk("%s: request GPIO %d for LED failed, ret = %d\n", DEVICE_NAME,
led_gpios[i], ret);
return ret;
}

s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT);
gpio_set_value(led_gpios[i], 1);
}

ret = misc_register(&tiny4412_led_dev);

printk(DEVICE_NAME"\tinitialized\n");

return ret;
}

static void __exit tiny4412_led_dev_exit(void) {
int i;

for (i = 0; i < LED_NUM; i++) {
gpio_free(led_gpios[i]);
}

misc_deregister(&tiny4412_led_dev);
}

module_init(tiny4412_led_dev_init);
module_exit(tiny4412_led_dev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");

上层测试程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>

int main(int argc,char *argv[])
{
int led_fd;
unsigned char ledflag = 0,num=0;

if(argc!=4)
{
printf("Usage:<%s> </dev/?node> <0/1> num\n",argv[0]);
return -1;
}

led_fd = open(argv[1],O_WRONLY);

ledflag = atoi(argv[2]);
num = atoi(argv[3]);
//write(led_fd, &ledflag,1);

ioctl(led_fd,ledflag,num);

}

Makefile

obj-m += leddriver.o
SOURCE = ledtest.o

CROSS_COMPLIE = arm-linux-
CC = $(CROSS_COMPLIE)gcc

KERNDIR = /centos/xyd/linux-3.5
#CURDIR = $(shell pwd)
CURDIR = `pwd`

.PHONY: module clean

all: module $(SOURCE:.o=)

module:
$(MAKE) -C $(KERNDIR) M=$(CURDIR) modules

$(SOURCE:.o=):$(SOURCE)
$(CC) -o [email protected] $^

%.o:%.c
$(CC) -c $<

clean:
$(MAKE) -C $(KERNDIR) M=$(CURDIR) clean
rm $(SOURCE:.o=)

仅供参考!!!!

时间: 2024-10-29 04:40:04

tiny4412字符设备的上层测试程序(底层驱动为/dev/leds)的相关文章

linux设备驱动第三篇:如何实现简单的字符设备驱动

在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分配的一些内存. 下面就开始学习如何写一个简单的字符设备驱动.首先我们来分解一下字符设备驱动 都有那些结构或者方法组成,也就是说实现一个可以使用的字符设备驱动我们必须做些什么工作. 1.主设备号和次设备号 对于字符设备的访问是通过文件系统中的设备名称进行的.他们通常位于/dev目录下.如下: [email pro

linux 驱动学习(一)简单的字符设备驱动程序

linux 系统将设备分为三种类型:字符设备.块设备和网络接口设备. 文章将先给出字符设备驱动程序,参照程序记录知识点,可能会不全,以后会慢慢加 .知识点记录完成后,会贴出字符设备驱动程序的测试程序并记录测试过程. 注释版 1 #include "linux/kernel.h" //内核头文件,含有一些内核常用函数的原形定义 2 #include "linux/module.h" //包含大量加载模块需要的函数和符号的定义 3 #include "linu

字符设备驱动之结构体

https://blog.csdn.net/tigerjibo/article/details/6412469 大部分驱动程序操作都涉及到三个重要的内核数据结构,分别是file_operations.file和inode,它们定义在<linux/fs.h> 1.file_operations:是一个函数指针的集合 1>应用程序和VFS之间的接口是系统调用,而VFS与磁盘文件系统以及普通设备之间的接口是file_operations结构体成员函数.file_operations结构体中成员

05 字符设备驱动

一.字符设备驱动函数接口 1.初始化cdev结构体void cdev_init(struct cdev * cdev, const struct file_operations * fops)功能:初始化cdev结构体参数:@cdev cdev结构体 @fops 操作函数的结构体 2.申请设备号int register_chrdev_region(dev_t from, unsigned count, const char * name);参数:@from 包含主设备号的数字 @count 设备

字符设备驱动(程序设计)—①

via:http://blog.sina.com.cn/s/blog_7ec8fc2c010157lc.html 1.驱动程序设计 1)驱动分类 驱动这里分为 字符设备驱动.网络接口驱动.块设备驱动!这三类,其中前两者是重点. ①.字符设备 字符设备是一种 按自己来访问 的设备,字符驱动则负责驱动字符设备,这样的驱动通常是先 open.close.read和write 系统调用! ②.块设备 在大部分 Unix 系统中,块设备不能按照字节处理数据,只能一次传送一个或则会多个长度是 512 字节(

从Linux内核LED驱动来理解字符设备驱动开发流程

目录 博客说明 开发环境 1. Linux字符设备驱动的组成 1.1 字符设备驱动模块加载与卸载函数 1.2 字符设备驱动的file_operations 结构体中的成员函数 2. 字符设备驱动--设备号注册卸载 2.1 设备号注册 2.2 设备号注销 3. 字符设备驱动--文件操作 参考资料 示例代码 @(从Linux内核LED驱动来理解字符设备驱动开发流程) 博客说明 撰写日期 2018.12.08 完稿日期 2019.10.06 最近维护 暂无 本文作者 multimicro 联系方式 [

linux驱动学习(1)——字符设备驱动开发

(一)驱动程序介绍 (a)Linux驱动程序学习 知识结构: 1. Linux驱动程序设计模式(40%) 2. 内核相关知识(30%) 3. 硬件相关知识(30%) (b)驱动分类: ①字符设备: 字符设备是一种按字节来访问的设备,字符驱动则负责驱动字符设备,这样的驱动通常实现 open, close,read和 write 系统调用. ②块设备: 在大部分的 Unix 系统, 块设备不能按字节处理数据,只能一次传送一个或多个长度是512字节( 或一个更大的 2 次幂的数 )的整块数据,而Lin

字符设备/块设备/网络设备

<字符设备> 字符设备的上层没有磁盘文件系统,所以字符设备的file_operations成员函数就直接由字符设备驱动提供(一般字符设备都会实现相应的fops集),因此file_operations 也就成为了字符设备驱动的核心. <块设备> 对于块设备而言,ext2,jiffs2,fat等文件系统会 实现针对VFS的file_opertations成员函数,所以设备驱动层将看不到file_opeations的存在.磁盘文件系统和设备驱动会将对磁盘上文件的访问转换成对磁盘上柱面和扇

指定子设备号创建字符设备

目录 指定子设备号字符设备 流程 实例程序 测试 title: 指定子设备号创建字符设备 tags: linux date: 2018/12/28 19:57:24 toc: true --- 指定子设备号字符设备 流程 内核中设备号分为主设备号和次设备号,以前注册字符设备驱动的时候,直接占用了主设备号包含了255个子设备号,也就是内核最多支持255个设备驱动(如果主设备号占据8位) 在Linux2.6中内核可以指定主设备号和对应的子设备号给一个fileoperation,如下图所示 流程如下: