上一篇文章实现了一个led驱动程序的模板,该模板虽然只是用于led驱动程序的编写,但是对于其它任何设备的驱动程序编写,其面向对象的思想都是可以借鉴和参考的。任何看似高深的技巧,都是从简单出发的,逐步深入。独孤九剑的最高境界就是无剑、无招,所有高深的变化都是从最基本的原理出发!
本文基于正点原子的imx6ull开发板实现board.c,led电路原理图和所用的GPIO引脚、配置方法见《led驱动实例》那篇文章
点击查看代码
//board_imx6ull.c
#include "led_orp.h"
#include "asm/memory.h"
#include "asm/uaccess.h"
#include "linux/err.h"
#include "linux/export.h"
#include "linux/kdev_t.h"
#include "linux/printk.h"
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.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>
#include <linux/printk.h>
#include <linux/init.h>
#include <asm/io.h>
static unsigned int *CCM_CCGR1;
static unsigned int *IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03;
static unsigned int *GPIO1_GDIR;
static unsigned int *GPIO1_DR;
int led_init(unsigned int which)
{
unsigned int val;
printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
/*
在配置寄存器前先进行地址映射
*/
if(!CCM_CCGR1 && which == 0)
{
CCM_CCGR1 = ioremap(0x20C406C, 4);
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = ioremap(0x20E0068, 4);
GPIO1_GDIR = ioremap(0X209C004, 4);
GPIO1_DR = ioremap(0X209C000, 4);
}
/*
使能GPIO1_IO03时钟
CCGR1[27:26] = b11
20C_406Ch
*/
val = *CCM_CCGR1;
val |= (0x3 << 26);
*(CCM_CCGR1) = val;
/*
配置IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03为GPIO模式
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03[3:0] = b0101
20E_0068h
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03暂时不使用,这是配置引脚的模式,比如上升沿,上下拉电阻等
*/
val = *IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03;
val &= ~(0xF); //低四位清零
val |= (0x5); //低四位赋值b0101
*(IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03) = val;
/*
配置GPIO1_GDIR寄存器使GPIO1_IO03配置为输出
GPIO1_GDIR[3] = 1
209_C004h
*/
*(GPIO1_DR) |= (0x1 << 3);
return 1;
}
int led_ctl(unsigned int which, char status)
{
printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
/*
根据status修改GPIO1_IO03的输出
GPIO1_DR
209_C000h
*/
if(which == 0)
{
if(status)
{
*GPIO1_DR &= ~(1 << 3);
printk("led on\n");
}
else {
*GPIO1_DR |= (1 << 3);
printk("led off\n");
}
}
return 0;
}
static struct led_operations led_orp = {
.init = led_init,
.ctl = led_ctl,
};
struct led_operations* get_led_operations()
{
return &led_orp;
}
基于上一篇文章中的模板,只需要实现board_imx6ull.c文件即可,其实就是实现led_orp.h头文件中的函数和结构体,从面向对象的角度来解释就是根据所用的开发板imx6ull创建一个led_orp对象,对象名board_imx6ull
标签:__,GPIO1,led,驱动程序,int,include,进阶 From: https://www.cnblogs.com/starstxg/p/18139245