赞
踩
基本概念了解
环境熟悉
eMMC: embedded Multi Media Card,嵌入式存储器标准规格
gzip压缩: Linux常见压缩工具,压缩为*.gz格式文件
常见内核文件:
内核源码结构:
内核组成部分:
运行在Windows下
可烧写uboot.imx,zImage,dtb,rootfs
问题1: litialize operation failed, please refer to “MfgTool.log” for detailed information, error code: 4.
问题2: Unassigned
尚未解决
Xshell通信
代码编译与运行
点灯
/home/uptech/fsl-6dl-source/kernel-3.14.28/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
内部有之前编译好的执行文件和驱动,可以直接使用
若没有,可以通过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
运行执行文件,效果:
Cortex-A7 MPCore架构(Multi-Processor)
关于IO和GPIO
启动方式
模式 | 描述 |
---|---|
USR | 用户模式,大部分程序运行模式,【非特权模式】 |
FIQ | Fast Interrupt rQuest, 快速中断模式 |
IRQ | Interrupt ReQuest,一般中断模式 |
SVC | SupVisor, 超级管理员模式,操作系统使用 |
MON | MONitor, 监视模式,用于安全拓展模式 |
ABT | ABorT,数据访问终止模式,用于虚拟存储、存储保护 |
HYP | HPYe-supervisor, 超级监视,用于虚拟化拓展r |
UNDef | 未定义指令终止模式 |
SYStem | 系统模式 |
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参数配置:
两个寄存器:
IO口功能配置:
GPIO时钟使能
Clock Control Module(CCM)
GPIO使能方式:
BOOT_MODE | 描述 |
---|---|
00 | FUSE启动 |
01 | 串行下载 |
10 | 内部BOOT模式 |
11 | 保留 |
ARM Linux驱动开发概述
字符设备驱动简介
字符设备驱动开发
字符设备:
Linux的应用程序如何调用驱动程序:
Linux一切皆文件,驱动操作文件位于/dev/device_name
应用程序运行在用户空间,驱动属于内核空间,用户必须系统调用才能调用内核空间实现对底层驱动的操作
include/linux/fs.h: struct file_operations
常用内核驱动操作函数
操作函数 | 函数功能 |
---|---|
owner | 该结构体的指针 |
llseek | 修改文件当前读写位置 |
read | 读取设备文件 |
write | 向设备文件写入数据 |
poll | 查询设备是否可以进行非阻塞读写 |
unlocked_ioctl | 提供对设备的控制功能,与应用程序ioctl 对应 |
mmap | 将设备的内存映射到进程空间(用户空间),帧缓冲设备会使用此函数,例如LCD显存 |
open | 打开设备文件 |
release | 释放(关闭)设备文件,与应用程序close 对应 |
fasvnc | 刷新待处理的数据,将缓冲区数据刷新到磁盘中 |
aio_fsync | 异步刷新待处理的数据 |
.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
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 采用GPL协议
MODULE_LICENSE('GPL');
// 作者 不必须加
MODULE_AUTHOR('***');
12 位
0 - 409520位
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可申请一段连续的,主设备号相同,次设备号不同的设备,此变量设置次设备号起始地址,一般为0count
要申请的设备号数量name
设备名称from
要释放的设备号count
从from开始,释放的设备号数量.dts
: 描述板级信息,开发板有哪些设备.dtsi
:描述SOC级信息,有几个CPU,主频、控制器信息DTB
:编译后的DTSDTC
:DTS编译器Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。