IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> (6) led驱动--分层设计--总线设备驱动模型 -> 正文阅读

[嵌入式](6) led驱动--分层设计--总线设备驱动模型

1.具体硬件控制---具体配置

//led_opr.h 
#ifndef _LED_OPR_H
#ifndef _LED_OPR_H

struct led_operations {
	int (*init)(int which);
	int (*ctl)(int which,char status);
};

struct led_operations *get_board_led_opr(void);

#endif
//led_resource.h
#ifndef _LED_RESOURCE_H
#define _LED_RESOURCE_H

//bit[31:16] = group
//bit[15:00] = which pin

#define GROUP(x) 		(x>>16)
#define PIN(x)			(x&0xFFFF)
#define GROUP_PIN(g,p)	((g<<16)|(p))

struct led_resource{
	int pin;
};

struct led_resource *get_led_resource(void);

#endif

2.分配/设置/注册platform_device结构体?

//board_A_led.c
#include "led_resource.h"

static struct resource resources[] = {
	{
		.start = GROUP_PIN(3,1),
		.FLAGS = IORESOURCE_IRQ,
	},
	{
		.start = GROUP_PIN(5,8),
		.flags = IORESOURCE_IRQ,
	},
}

static struct platfrom_device board_A_led_dev = {
	.name = "100ask_led",
	.num_resources = ARRY_SIZE(resources),
	.resource = resources,
};

static int led_dev_init(void)
{
	int err;
	
	err = platform_device_register(&board_A_led_dev);
	
	return 0;
}

static void led_dev_exit(void)
{
	int err;
	
	platform_device_unregister(&board_A_led_dev);
	
	return 0;
}

3.分配/设置/注册platform_driver结构体

//chip_demmo_gpio.h
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#incldue <linux/miscdevice.h>
#include <linux/kernel.h>
#incldue <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#incldue <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#incldue <linux/tty.h>
#include <linux/kmod.h>
#incldue <linux/gfp.h>
#incldue "led_opr.h"
#incldue "led_resource.h"

static int g_ledpins[100];
static int g_ledcnt = 0;

static int board_demo_led_init(int which)
{
	printk("init gpio:group %d,pin %d\n",GROUP(g_ledpins[which]),PIN(g_ledpins[which]));
	switch(GROUP(g_ledpins[which]))
	{
		case 0:
		{
			printk("init pin of group 0 ...\n");
			break;
		}
		case 1:
		{
			printk("init pin of group 1 ...\n");
			break;
		}
		case 2:
		{
			printk("init pin of group 2 ...\n");
			break;
		}
		case 3:
		{
			printk("init pin of group 3 ...\n");
			break;
		}
	}
	
	return 0;
}

static int board_demo_led_ctl(int which, char status)
{
	printk("set led %s:group %d,pin %d\n",status?"on":"off",GROUP(g_ledpins[which]),PIN(g_ledpins[which]));
	switch(GROUP(g_ledpins[which]))
	{
		case 0:
		{
			printk("set pin of group 0 ...\n");
			break;
		}
		case 1:
		{
			printk("set pin of group 1 ...\n");
			break;
		}
		case 2:
		{
			printk("set pin of group 2 ...\n");
			break;
		}
		case 3:
		{
			printk("set pin of group 3 ...\n");
			break;
		}
	}
	return 0;
}

static struct led_operations board_demo_led_opr = {
	.num  = 1,
	.init = board_demo_led_init,
	.ctl  = board_demo_led_ctl,
};

static int chip_demo_gpio_led_probe(struct platform_device *dev)
{
	int i = 0;
	struct resource *res;
	
	which(1)
	{
		res = platform_get_resource(dev,IORESOURCE_IRQ,i++);
		if(!res)
			break;
		g_ledpins[g_ledcnt] = res->start;
		led_device_create(g_ledcnt);
		g_ledcnt++;
	}
	return 0;
}

static int chip_demo_gpio_led_remove(struct platform_device *dev)
{
	int i;
	for(i=0;i<g_ledcnt;i++)
	{
		led_device_destroy(i);
	}
	g_ledcnt = 0;
	
	return 0;
}

static struct platform_driver chip_demo_gpio_drv = {
	.probe		= chip_demo_gpio_led_probe,
	.remove		= chip_demo_gpio_led_remove,
	.driver		= {
		.name 	= "100ask_led",
	},
};

static int chip_demo_gpio_drv_init(void)
{
	int err;
	err = platform_deiver_register(&chip_demo_gpio_drv);
	register_led_operations(&board_demo_led_opr);
	
	return 0;
}

static void chip_demo_gpio_drv_exit(void)
{
	platform_drvier_unregister(&chip_demo_gpio_drv);
}

module_init(chip_demo_gpio_drv_init);
module_exit(chip_demo_gpio_drv_exit);
MODULE_LICENSE("GPL");

4.led驱动框架部分?

//leddrv.c
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#incldue <linux/kernel.h>
#incldue <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>

#incldue "led_opr.h"

static int major = 0;
static struct class *led_class;
static led_operations *p_led_opr;

#define MIN(a,b) (a<b?a:b)

void led_device_create(int minor)
{
	device_create(led_class,NULL,MKDEV(major,minor),NULL,"100ask_led%d",minor);
}

void led_device_distroy(int mintor)
{
	device_destroy(led_class,MKDEV(major,0));
}

void register_led_operations(struct led_operations *opr)
{
	p_led_opr = opr;
}

EXPORT_SYMBOL(led_device_create);
EXPORT_SYMBOL(led_device_distroy);
EXPORT_SYMBOL(register_led_operations);

static ssize_t led_drv_read(struct file *file,char __user *buf,size_t size,loff_t *offset)
{
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	return 0;
}

static ssize_t led_drv_write(struct file *file,const char __user *buf,size_t size,loff_t *offset)
{
	int err;
	char status;
	struct inode *inode = file_inode(file);
	int minor = iminor(inode);
	
	printk("%s %s line %d\n"__FILE__,__FUNCTION__,__LINE__);
	err = copy_from_user(&status,buf,1);
	
	p_led_opr->ctl(minor,status);
	
	return 1;
}
static int led_drv_open(struct inode *node,struct file *file)
{
	int minor = iminor(node);
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	p_led_opr->init(minor);
	
	return 0;
}
static int led_drv_close(struct inode *node,struct file *file)
{
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	return 0;
}

static struct file_operations led_drv = {
	.owner 	= THIS_MODULE,
	.open   = led_drv_open,
	.read   = led_drv_read,
	.write  = led_drv_write,
	.release= led_drv_close,
};

static int __init led_init(void)
{
	int err;
	int i;
	
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	major = register_chrdev(0,"100ask_led",&led_drv);
	
	led_class = class_create(THIS_MODULE,"100ask_led_class");
	err = PTR_ERR(led_class);
	if(IS_ERR(led_class)){
		printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
		unregister_chrdev(major,"led");
		return -1;
	}
	
	return 0;
}

static void __exit led_exit(void)
{
	int i;
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	
	class_destroy(led_class);
	unregister_chrdev(major,"100ask_led");
}

module_init(led_init);
module_exit(led_exit);

MODULE_LICENSE("GPL");

5.应用例程??

//ledtest.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

/*
 * ./ledtest /dev/100ask_led0 on
 * ./ledtest /dev/100ask_led0 off
 */
int main(int argc, char **argv)
{
	int fd;
	char status;
	
	/* 1. 判断参数 */
	if (argc != 3) 
	{
		printf("Usage: %s <dev> <on | off>\n", argv[0]);
		return -1;
	}

	/* 2. 打开文件 */
	fd = open(argv[1], O_RDWR);
	if (fd == -1)
	{
		printf("can not open file %s\n", argv[1]);
		return -1;
	}

	/* 3. 写文件 */
	if (0 == strcmp(argv[2], "on"))
	{
		status = 1;
		write(fd, &status, 1);
	}
	else
	{
		status = 0;
		write(fd, &status, 1);
	}
	
	close(fd);
	
	return 0;
}


?6.Makefile??

# 1. 使用不同的开发板内核时, 一定要修改KERN_DIR
# 2. KERN_DIR中的内核要事先配置、编译, 为了能编译内核, 要先设置下列环境变量:
# 2.1 ARCH,          比如: export ARCH=arm
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
# 2.3 PATH,          比如: export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
 
 
# 参考内核源码drivers/char/ipmi/Makefile
# obj-m += ab.o
 
 
KERN_DIR = /home/book/100ask_imx6ull-sdk/Linux-4.9.88
 
all:
	make -C $(KERN_DIR) M=`pwd` modules
	$(CROSS_COMPILE)gcc -o ledtest ledtest.c
	
clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order
	rm -f ledtest
	
obj-m += leddrv.o chip_demo_gpio.o board_A_led.o

此笔记为学习韦东山老师教程的记录

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-01-24 11:03:47  更:2022-01-24 11:04:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 12:23:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码