大家好,今天主要和大家聊一聊,编写Linux驱动格式与方法。
目录
第一:基本格式实验
1、编写外设结构体
2、定义IO复用寄存器组的基地址
3、定义访问指针
第二:实验程序编写
第一:基本格式实验
可以利用模仿C语言中结构体成员地址递增的特点将某个外设的所有寄存器写入到一个结构体里面,然后定义一个结构体指针指向这个外设的寄存器基地址,这样我们就可以通过这个结构体指针来访问这个外设的所有寄存器。
1、编写外设结构体
将同属于一个外设的所有寄存器编写到一个结构体里面,IO复用寄存器的结构体如下:
typedef struct
{
volatile unsigned int BOOT_MODE0;
volatile unsigned int BOOT_MODE1;
volatile unsigned int SNVS_TAMPER0;
volatile unsigned int SNVS_TAMPER1;
......
}IO_SW_MUX_Type;
2、定义IO复用寄存器组的基地址
根据结构体IO_SW_MUX_Type的定义,其定义成员变量为BOOT_MODE0,也就是BOOT_MODE0这个IO的IO复用寄存器的基地址就是0X020E0014。
#define IOMUX_SW_MUX_BASE (0X020E0014)
3、定义访问指针
访问指针定义如下:
#define IOMUX_SW_MUX ((IOMUX_SW_MUX_Type *)IOMUX_SW_MUX_BASE)
通过上面三步就可以通过“IOMUX_SW_MUX->GPIO1_IO03”来访问 GPIO1_IO03 的 IO 复用寄存器了。同样的,其他的外设寄存器都可以通过这三步来定义。
第二:实验程序编写
在编写寄存器结构体时候注意寄存器的地址是否连续,有些外设的寄存器地址可能不是连续的,会保留一些地址。
#include "hello.h"
void clk_enable(void)
{
CCM->CCGR0 = 0XFFFFFFFF;
CCM->CCGR1 = 0XFFFFFFFF;
CCM->CCGR2 = 0XFFFFFFFF;
CCM->CCGR3 = 0XFFFFFFFF;
CCM->CCGR4 = 0XFFFFFFFF;
CCM->CCGR5 = 0XFFFFFFFF;
CCM->CCGR6 = 0XFFFFFFFF;
}
//初始化LED对应的GPIO
void led_init(void)
{
IOMUX_SW_MUX->GPIO1_IO03 = 0X5; /* 复用为 GPIO1_IO03 */
//配置GPIO1_IO03的IO属性
IOMUX_SW_PAD->GPIO1_IO03 = 0X10B0;
//初始化GPIO
GPIO1->GDIR = 0X0000008; /* GPIO1_IO03 设置为输出 */
//设置 GPIO1_IO03 输出低电平,打开 LED0
GPIO1->DR &= ~(1 << 3);
}
int main(void)
{
clk_enable(); /* 使能所有的时钟 */
led_init(); /* 初始化 led */
while(1) /* 死循环 */
{
led_off(); /* 关闭 LED */
delay(500); /* 延时 500ms */
led_on(); /* 打开 LED */
delay(500); /* 延时 500ms */
}
return 0;
}
总结:利用Makefile对源码文件进行编译,生产对应的可执行文件,烧写到开发板上可以观察到灯亮灭情况。