i.MX6驱动开发学习日志

i.MX6驱动开发学习日志


Day 1 【了解常识】

基本概念了解
环境熟悉


1.1 MCIMX6U8DVM10AB 芯片概述

  • 32位MPU
  • 双核ARM - Cortex-A9
  • 1GHz主频
  • 芯片命名方式:
    在这里插入图片描述

1.2 关于Linux内核的一些基础概念

  • eMMC: embedded Multi Media Card,嵌入式存储器标准规格

  • gzip压缩: Linux常见压缩工具,压缩为*.gz格式文件

  • 常见内核文件:

    • vmlinux: 编译出来的原始内核文件
    • zImage: 经过gzip压缩的vmlinux
    • bzImage: big zImage,内核较大需要用bzImage,占用内存1M以上
    • uImage: U-boot专用映像文件
    • vmlinuz: zImage/bzImage的拷贝或链接
    • initrd: initial ramdisk,引导硬件可被实际内核vmlinuz接管
  • 内核源码结构:

    • arch: 硬件架构
    • block: 块设备驱动程序I/O调度
    • crypto: 常用加密、散列、压缩、校验算法
      • crypto-【英文前缀】保密的
      • crypto-community,地下党
      • cryptography,密码学
    • Documentation: 内核各部分的注释
    • drivers: 设备驱动程序
    • fs: file system,文件系统
    • include: 头文件
    • init: 内核初始化代码
    • ipc: 进程间通信代码
    • kernel: 内核核心部分,包括进程调度、定时器
    • lib: 库文件
    • mm: memory manage,内存管理
    • net: 网络代码
    • scripts: 用于配置内核的脚本
    • security: SELinux模块
    • sound: 音频设备驱动代码
    • usr: 用于打包和压缩的cpio
      • cpio: copy input output,用来建立、还原备份档的工具程序

    在这里插入图片描述

  • 内核组成部分:

    • 进程调度 - SCHED
    • 内存管理 - MM
    • 虚拟文件系统 - VFS
    • 网络接口 - NET
    • 进程间通信 - IPC
      在这里插入图片描述

1.3 Linux嵌入式开发基本概念

  • 单片机简单的操作系统:
    • UCOS,FreeRTOS
    • 只具备Kernel
    • 网络、文件系统、GUI等需要移植
  • 可移植操作系统的嵌入式开发:
    • 底层驱动开发:
      • 裸机开发:
        • 不具备IDE - 安装交叉编译环境
      • Linux操作系统开发:
        • 系统移植:
          • 移植Uboot(一种bootloader代码,用于启动Linux内核)
          • 移植Linux内核
          • 移植根文件系统(rootfs),包含常用命令和文件
            在这里插入图片描述
        • 三大驱动:
          • 字符设备驱动
          • 块设备驱动
          • 网络设备驱动
    • 应用开发
      (待)

1.4 关于交叉编译器

  • Ubuntu 自带的gcc编译器是针对x86架构的
  • 在x86架构的PC上安装的、可以编译ARM架构代码的、GCC编译器 - 交叉编译器

1.5 MfgTool系统烧入工具

  • 运行在Windows下

  • 可烧写uboot.imx,zImage,dtb,rootfs

  • 问题1: litialize operation failed, please refer to “MfgTool.log” for detailed information, error code: 4.
    在这里插入图片描述

    • 我出现这个问题的原因是我将mfgtools解压在移动硬盘里,可能系统需要获取管理员权限才能执行脚本,将mfgtools文件夹改到其他硬盘里问题就解决了
  • 问题2: Unassigned
    尚未解决
    在这里插入图片描述

1.6 Linux 文件系统

  • 文件系统:
    • 将二进制数据翻译为人类语言的文件格式
    • 不同的物理结构需要不同的文件系统管理

Day 2 【熟悉环境】

Xshell通信
代码编译与运行
点灯


2.1 查看原理图

  • 点灯用的是开发板P8的4个引脚
    在这里插入图片描述

2.2 设备树文件

  • 设备树文件 imx6qdl-sabresd.dtsi
    • 路径 /home/uptech/fsl-6dl-source/kernel-3.14.28/arch/arm/boot/dts/imx6qdl-sabresd.dtsi

2.3 运行代码

  • i.MX6 开发板
    • 内部有之前编译好的执行文件驱动,可以直接使用
      在这里插入图片描述

    • 若没有,可以通过NFS共享将Ubuntu虚拟机的/imx6文件夹挂载到开发板的/mnt目录下

      • 在Xshell里对开发板运行指令

      • 用网线接好开发板与电脑,确保主机、虚拟机、开发板处于同一网段下
        在这里插入图片描述
        在这里插入图片描述

        在这里插入图片描述

      • 通过Xshell使用命令ifconfig eth0 192.168.1.130可改变开发板的地址

      • 通过Xshell使用命令mount -t nfs 192.168.1.120:/imx6 /mnt/可将虚拟机下的 /imx6 文件夹 挂载到开发板的 /mnt/ 文件夹

    • insmod ./driver/LEDBuzzer.ko 加载驱动

    • ./LEDBuzzer 运行执行文件,效果:
      在这里插入图片描述


Day 3 【裸机开发了解】

Cortex-A7 MPCore架构(Multi-Processor)
关于IO和GPIO
启动方式


3.1 Cortex-A处理器运行模式(9种)

模式描述
USR用户模式,大部分程序运行模式,【非特权模式】
FIQFast Interrupt rQuest, 快速中断模式
IRQInterrupt ReQuest,一般中断模式
SVCSupVisor, 超级管理员模式,操作系统使用
MONMONitor, 监视模式,用于安全拓展模式
ABTABorT,数据访问终止模式,用于虚拟存储、存储保护
HYPHPYe-supervisor, 超级监视,用于虚拟化拓展r
UNDef未定义指令终止模式
SYStem系统模式

3.2 关于 I/O

  • IOMUX Controller,IO复用控制

  • 32位软件复用控制寄存器,32-bit software mux control registers

  • IO命名: IOMUXC_SW_MUC_CTL_PAD_XX_XX, XX_XX为IO口功能,例如UART1_TX_DATA

  • IO复用功能查询: IMX6SDLRM.pdf手册Charpter4 - External Signals and Pin Multiplexing
    在这里插入图片描述

  • IO和GPIO的差别:

    • IO是宏观的
    • GPIO是IO的一种工作方式,比如说点亮LED、按键输入等操作
  • IO参数配置:

    • 两个寄存器:

      • IOMUXC_SW_MUX_CTL_PAD_XX_XX,配置复用功能
      • IOMUXC_SW_PAD_CTL_PAD_XX_XX,配置IO参数:
        在这里插入图片描述
        • HYS: Hysteresis comparator,施密特触发器使能,施密特触发器的迟滞现象
        • PUS: Pull Up/down Set,上下拉电阻
        • PUE: Pull Up/down Enable,上下拉/状态保持器
        • PKE: 使能/失能上下拉/状态保持器
        • ODE: 使能/使能IO开路输出
        • SPEED: IO速度
        • DSE: IO驱动能力
        • SRE: Slew Rate,压摆率
    • IO口功能配置:
      在这里插入图片描述

  • GPIO时钟使能

    • 时钟系统Clock Control Module(CCM)
    • 门控寄存器 - CCM Clock Gating Register
      • CCM_CCGRx [0, 6]
  • GPIO使能方式:

    • 使能时钟
    • 设置复用功能
    • 设置IO参数
    • 配置GPIO参数

3.3 启动方式

BOOT_MODE描述
00FUSE启动
01串行下载
10内部BOOT模式
11保留

Day 4 字符设备

ARM Linux驱动开发概述
字符设备驱动简介
字符设备驱动开发


4.1 ARM Linux驱动开发概述

  • 三大类驱动:`
    • 字符设备驱动:
      • GPIO
      • I2C
      • SPI 等
    • 块设备驱动:
      • 存储器设备的驱动
      • EMMC
      • NAND
      • SD
      • U盘等
    • 网络设备驱动:
      • USB WIFI

4.2 字符设备驱动简介

  • 字符设备:

    • 通过字节流进行读写操作的设备
  • Linux的应用程序如何调用驱动程序:
    在这里插入图片描述

  • Linux一切皆文件,驱动操作文件位于/dev/device_name

  • 应用程序运行在用户空间,驱动属于内核空间,用户必须系统调用才能调用内核空间实现对底层驱动的操作
    在这里插入图片描述

    • 应用程序使用的函数,在具体驱动中都有与之对应的函数
      • 应用程序调用open,驱动程序也要有open
      • 内核驱动操作函数集合include/linux/fs.h: struct file_operations
  • 常用内核驱动操作函数

操作函数函数功能
owner该结构体的指针
llseek修改文件当前读写位置
read读取设备文件
write向设备文件写入数据
poll查询设备是否可以进行非阻塞读写
unlocked_ioctl提供对设备的控制功能,与应用程序ioctl对应
mmap将设备的内存映射到进程空间(用户空间),帧缓冲设备会使用此函数,例如LCD显存
open打开设备文件
release释放(关闭)设备文件,与应用程序close对应
fasvnc刷新待处理的数据,将缓冲区数据刷新到磁盘中
aio_fsync异步刷新待处理的数据

4.3 字符设备驱动开发

  • 加载和卸载:
    • Linux驱动两种运行方式:
      • 编译进内核,开机自启
      • 编译成模块(.ko文件),insmod xxx.ko加载模块,调试阶段使用
        • 模块加载 module_init(xxxx_init)
          • insmod时调用xxxx_init
        • 模块卸载module_exit(xxxx_exit)
          • rmmod时调用xxxx_exit
// 字符设备驱动模块加载和卸载函数模板

/* 驱动入口函数 */
static int __init xxx_init(void){ 
	return 0;  
} 

/* 驱动出口函数 */
static void __exit xxx_exit(void){
	
}

/* 将上面两个函数指定为驱动的入口和出口函数 */
module_init(xxx_init);
module_exit(xxx_exit);
  • insmod 与 modprobe 指令比较

    • insmod
      • 简单
      • 但不能决定模块的依赖关系
      • dvc_1.ko 依赖于 dvc_2.ko
        • insmod dvc_2.ko
        • insmod dvc_1.ko
      • 卸载驱动insmod dvc_1.ko
    • modprobe
      • 智能化加载驱动
      • 卸载驱动modprove -r dvc_1.ko
      • 会卸载掉驱动的依赖
      • 需要防止依赖项有多个驱动在使用
  • 字符设备注册与注销

    • 注册字符设备:
      • cat/proc/devices查看已注册的设备号,不可重复
        在这里插入图片描述
      • register_chrdev(***),参数:
        • 主设备号
        • 设备名称
        • 操作函数合集结构体的拷贝
// 字符设备注册和注销

// 操作函数集合结构体变量 test_fops
// 尚未定义open release等成员函数
static struct file_operations test_fops; 

/* 驱动入口函数 */
static int __init xxx_init(void){ 

	int retvalue = 0; 
	
	// 注册字符设备驱动
	// 主设备号200
	// 设备名称 chrtest
	// 结构体拷贝 &test_fops
	retvalue = register_chrdev(200, "chrtest", &test_fops);
	
	if(retvalue < 0){
		// 字符设备注册失败,自行处理 
	}
	
	return 0;
}


/* 驱动出口函数 */
static void __exit xxx_exit(void){

	// 注销字符设备驱动 
	unregister_chrdev(200, "chrtest");
}

/* 将上面两个函数指定为驱动的入口和出口函数 */
module_init(xxx_init);
module_exit(xxx_exit);
  • 设备具体操作函数

  • 设备打开chrtest_open()

/* 打开设备 */
static int chrtest_open(struct inode *inode, struct file *filp){ 
	return 0; 
}
  • 从设备读取chrtest_read()
/* 从设备读取 */
static ssize_t chrtest_read(struct file *filp, char __user *buf, 
size_t cnt, loff_t *offt){
	return 0;
}
  • 向设备写数据chrtest_write()
/* 向设备写数据 */
static ssize_t chrtest_write(struct file *filp,
const char __user *buf,
size_t cnt, loff_t *offt){
	return 0;
}
  • 释放设备chrtest_release()
/* 关闭 /释放设备 */
static int chrtest_release(struct inode *inode, struct file *filp){
	return 0;
}
  • 用以上定义好的函数来初始化结构体 struct file_operations test_fops
static struct file_operations test_fops = {
	.owner = THIS_MODULE, 
	.open = chrtest_open,
	.read = chrtest_read,
	.write = chrtest_write,
	.release = chrtest_release,
};
  • 驱动入口 xxx_init()
/* 驱动入口函数 */
static int __init xxx_init(void){

	int retvalue = 0;

	/* 注册字符设备驱动 */
	retvalue = register_chrdev(200, "chrtest", &test_fops);
	
	if(retvalue < 0){
		/* 字符设备注册失败,自行处理 */
	}
	return 0;
}
  • 驱动出口xxx_exit()
/* 驱动出口函数 */
	static void __exit xxx_exit(void){
	/* 注销字符设备驱动 */
	unregister_chrdev(200, "chrtest");
}
  • 入口/出口指定
	module_init(xxx_init);
	module_exit(xxx_exit);
  • 添加LICENSE(必须加)
// LICENSE 采用GPL协议
MODULE_LICENSE('GPL');
// 作者 不必须加
MODULE_AUTHOR('***');
  • Linux设备号
    • 主设备号
      • 具体的驱动
      • 12 位 0 - 4095
    • 次设备号
      • 驱动的各个设备
      • 20位
    • 定义位置
      • include/linux/types.h
    • 分配方式
      • 静态分配
        • cat/proc/devices 查看已分配的设备号
      • 动态分配
        • int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
        • dev 保存32位设备号
        • baseminor alloc_chrdev_region可申请一段连续的,主设备号相同,次设备号不同的设备,此变量设置次设备号起始地址,一般为0
        • count要申请的设备号数量
        • name设备名称
        • from 要释放的设备号
        • count 从from开始,释放的设备号数量

Day 5 设备树


  • .dts: 描述板级信息,开发板有哪些设备
  • .dtsi:描述SOC级信息,有几个CPU,主频、控制器信息
  • DTB:编译后的DTS
  • DTC:DTS编译器
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chorgy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值