ARM-Linux 完全入门
1.准备部分
1.1 虚拟机安装
- 准备VMware软件、ubuntu系统镜像
- 安装过程
- VMware安装
破解(自己百度破解码,多试几个网址,会有能用的) - Ubuntu安装
- 配置联网
桥接
虚拟机Ubuntu系统必须能连接到外网,不然不能更新软件安装包
配置虚拟机网络
第一步
1.重启虚拟机网络编辑器(还原配置)
第二步
2.重启虚拟机网络适配器(移除再添加)
第三步
3.重启虚拟机网络服务器
sudo service network-manager stop
sudo rm /var/lib/NetworkManager/NetworkManager.state
sudo service network-manager start
1.2 板子获取
2.Linux基础命令
2.1.操作方式
2.1.1界面
2.1.2命令行
- 打开终端 Ctrl+Alt+t
- 一个窗口打开第二个 Ctrl+Shift+t
- 新窗口打开第二个 Ctrl+Alt+t
- 字体放大 Ctrl+(+)
- 字体缩小 Ctrl+(-)
2.2 文件和目录操作
ls -l -a lsusb lsmod
cd ~ …
pwd
mkdir
touch
rm
mv
cat
2.3 管理员
2.3.1 管理员权限
sudo
2.3.1 管理员用户
创建root用户 sudo passwd root
切换用户 su + 用户名
2.4 安装应用
2.4.1 apt
- sudo apt install (package name)
- sudo apt update 使用 apt 更新包数据库
- sudo apt upgrade 使用 apt 升级已安装的软件包
2.4.2 换源
2.4.2.1 界面方式
- 点Ubuntu左下角菜单,选紫色的SoftWare&Updates 软件
- 点Download from 选择other
- 再选择C开头的china,然后点mirrors.aliyun.com,最后点Choose Server
- 进行密码验证 最后点close
- 然后点reload
- sudo apt update
- sudo apt upgrade
2.4.2.1 命令方式
一切皆文件
2.5 文本处理
2.5.1 vim
2.5.1.1安装方式
sudo apt install vim
2.5.1.2使用方法
2.5.1.2.1命令模式
默认,此模式下,可使用方向键(上、下、左、右键)或 k、j、h、i 移动光标的位置,还可以对文件内容进行复制、粘贴、替换、删除等操作
2.5.1.2.2输入模式
使 Vim 进行输入模式的方式是在命令模式状态下输入 i、I、a、A、o、O 等插入命令,当编辑文件完成后按 Esc 键即可返回命令模式
快捷键
小写i/a :在当前光标所在位置插入随后输入的文本,光标后的文本相应向右移动
小写x:删除光标所在位置的字符(命令模式下)
小写dd:删除光标所在行(命令模式下)
2.5.1.2.3编辑模式
编辑模式用于对文件中的指定内容执行保存、查找或替换等操作。在命令模式状态下按“:”键,此时 Vim 窗口的左下方出现一个“:”符号,这是就可以输入相关指令进行操作了
相关命令
- Esc +:wq
- Esc +:wq!
- Esc+:q
- Esc+:!
- 显示行 Esc + :set nu
- 搜索文本 :Esc+:/文本
查看上一个: N 查看下一个 :n
2.5.2 gedit
2.5.3 nano
2.6 缩和解压缩
tar
打包示例 tar -cvf test.tar*.c
解压示例 tar -xvf test.tar
2.7 查找
2.7.1 find
查找文件
sudo find /home/ling -name "*.c'
2.7.2 grep
查找文件中的字符
grep "d" a.c
dmesg
dmesg | grep usb
2.8 基础编辑测试
- gcc
sudo apt install gcc
编译 gcc - file
- chmod
文件所有者(Owner)
用户组(Group)
其它用户(Other Users)
sudo chmod 777 test.c
2.9 misc
- ifconfig
- echo
- ping
- ps axu 查看系统中所有运行进程
- top
- kill
- uname -a
- shutdown 60秒延时关闭系统
shutdown now 立即关闭 - reboot
- ctrl+c 终止进程 SIGINT
- ctrl+z 挂起程序
-jobs 查看当前终端的后台任务
fg 将挂起的任务恢复到前台运行
bg 将挂起的任务放到后台继续运行
kill %1 终止编号为1的后台任务
3.环境搭建
3.1 注意
串口: windows要选择到底连接哪里(windows/linux)
Windows关机之前,虚拟机要关闭
3.2 ssh(方便切换)
3.2.1Ubuntu
sudo apt-get install openssh-server
ifconfig
3.2.2Windows
MobaXterm
3.3 传文件
3.3.1 FTP
3.3.1.1Ubuntu
- sudo apt-get install vsftpd
- sudo vim /etc/vsftpd.conf
找到 #write_enable=YES
把#删掉,然后保存
- sudo /etc/init.d/vsftpd restart
3.3.1.2 Windows
安装 FileZilla
3.3.2.3 注意:
如果连接不上,关闭Linux(sudo ufw disable)和Windows防火墙
3.3.2 samba
3.3.2.1Ubuntu
1.sudo apt-get upgrade
2.sudo apt-get update
3.sudo apt-get dist-upgrade
4.sudo apt-get install samba samba-common
5.samba -V #如果出现下面版本号说明已经安装了samba服务器
6.sudo mkdir /home/share
7.sudo chmod 777 /home/share
8.sudo smbpasswd -a ling#需要确认输入两个相同的密码确认
9.sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak #备份 smb.conf 配置文件
10.sudo vim /etc/samba/smb.conf #在配置文件smb.conf的最后添加下面的内容(里面的信息要改成自己的)
11.sudo service smbd restart(或者/etc/init.d/samba restart) #重启samba服务器
[global]; 创建工作组 设定 Samba Server 所要加入的工作组或者域 workgroup = WORKGROUP ; 为了防止出现中文目录乱码的情况。其中根据你的local,UTF-8 有可能需要改成 cp936; display charset = UTF-8unix charset = UTF-8dos charset = cp936 ; 是否允许guest用户访问guest ok = no; 注:如果 #security 存在就直接修改,不存在就创建; security = user ; 安全模式 我们设置用户安全级别security = user ; 说明:用来定义用户名映射,比如可以将root换成administrator、admin等。不过要事先在smbusers文件中定义好。; 比如:root = administrator admin,这样就可以用administrator或admin这两个用户来代替root登陆Samba Server,更贴近windows用户的习惯。username map = /etc/Samba/smbusers ; 共享名,该共享标签,该名字为在电脑上看到的共享名 注意网络映射的路径是这标签名字不是共享路径的名字
[share]; 该共享描述comment = Shared Folder with username and password ; 共享文件夹路径path = /home/ling/; 表示是否允许匿名访问该共享目录public = no; 配置的Samba访问账号 指明可以访问的用户valid users = ling; 表示是否可以在 Window Explorer中显示该目录browsable = no; 指明新建立的文件的属性create mask = 777 ; 指明新建立的目录的属性directory mask = 777; force group 和force user 规定创建的文件或文件夹的拥有者和组拥有者是谁 ; 一般这两个值来空,则表示拥有者和组拥有者为创建文件者。 如设定值,如force group=ling; Force user=yhq,则不管是谁创建的文件和文件夹,拥有者都为yhq和yhq组。; force user强制把建立文件的属主是谁。如果我有一个目录,让guest可以写,那么guest就可以删除,; 如果我用force user=yhq强制建立文件的属主是yhq,同时限制create mask = 0755,; 这样guest就不能删除了。force user = lingforce group = ling; available用来指定该共享资源是否可用available = yes ; 共享路径读权限 设置共享是否可浏览,如果no则表示隐藏,需要通过"//ip/共享目录"进行访问browseable = yes; 共享路径写权限writable = yes
3.3.2.2 Windows
-
打开文件管理器
点击此电脑 -
选择映射网络驱动器
-
添加
\虚拟机IP地址\share
eg:\192.168.31.169\share -
输入用户名&密码
3.3.2.3 注意
如果连接不上,关闭Linux(sudo ufw disable)和Windows防火墙
3.3.3 scp
3.3.4 共享文件夹
4.系统编译
4.1 交叉编译器安装
- cd /usr/local
sudo mkdir arm
cd arm - 把交叉编译工具链拷贝到/usr/local/arm文件夹(FTP)
sudo chmod 777 arm - 解压 sudo tar -vxf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz
- 环境变量修改
- 查看环境变量
env
printenv
echo $PATH - 修改环境变量
sudo vim /etc/profile
最后面新一行添加
export PATH=$PATH:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin
- 重启sudo reboot
- 测试 arm-linux-gnueabihf-gcc -v
- 编译
4.2 Uboot
4.2.1综述
是一套裸机程序,可以理解为板子上电的初始化
Uboot的源代码,启动流程,都值得分析,面试会问
4.2.2 编译
- 安装编译必用工具
sudo apt-get install lzop libncurses5-dev u-boot-tools
- 拷贝迅为Uboot源代码
cd ~
mkdir Linux
mkdir uboot
cd uboot
拷贝FTP
- 解压
tar -xvf uboot-imx-rel_imx_4.1.15_2.1.0_ga_20200512.tar.gz
cd uboot-imx-rel_imx_4.1.15_2.1.0_ga/
- 编译
./create.sh
sudo apt install make
Makefile
- .config
- make menuconfig
- Kconfig
- 生成文件
- uboot.imx
- uboot.bin
4.2.3流程
4.2.3.1汇编部分
- 关
- 中断
- 看门狗
- cache
- mmu
- …
- 进入SVC模式
- 基本硬件初始化
- 时钟
- 串口
- flash
- 闪存
- 初始化堆栈
- 自搬移
- 重定位
- 内存运行块
4.2.3.1C语言部分
- 初始化大部分硬件
- 网卡
- 屏幕
- usb
- …
- 把内核搬到内存
4.2.4Uboot源码简要分析
4.2.4.1汇编部分
- 跳转到reset
arch/arm/lib/vectors.S
- arch/arm/cpu/armv7/start.S
-
reset
-
cpu_init_cp15
-
cpu_init_crit
-
arch/arm/cpu/armv7/lowlevel_init.S
-
arch/arm/lib/crt0.S
4.2.4.1C语言部分
-
common/board_f.c
board_init_f
-
common/board_r.c
board_init_r
run_main_loop
-
common/main.c
4.2.5 create.sh
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make distclean
make mx6ul_topeet_emmc_defconfig #.config
make #Makefile
怎么修改.config? make menuconfig
menuconfig界面怎么生成的? Kconfig
4.3 内核
4.3.1 编译过程
- 拷贝迅为kernel源代码
cd ~
cd Linux
mkdir kernel
cd kernel
拷贝 FTP
- 解压
tar -xvf linux-imx-rel_imx_4.1.15_2.1.0_ga_20200903.tar.gz
cd linux-imx-rel_imx_4.1.15_2.1.0_ga
- 编译
./create.sh - 编译后自动生成的文件
- arch/arm/boot
image 非压缩文件
zimage
uimage - arch/arm/boot/dts 设备树
4.3.2 内核源码
- 各个文件都是什么意思
- 源码查看软件 Source Insight 4.0
- 把解压完的内核源码从虚拟机拷贝到Windows
- 新建Source Insight工程
4.3.3 编译脚本
- #!/bin/bash
bash脚本 - make imx_v7_defconfig
- arch\arm\configs
- .config
- make uImage LOADADDR=0x10008000 -j16
- make modules
- 驱动编译的两种方式
- 将驱动编译进内核:obj-y:yes内建
- 将驱动编译进ko文件:obj-m:module模块
- make *.dtb
4.1 设备树
4.1.1功能
包含芯片&板子 外设信息
系统驱动会匹配设备树,匹配成功后加载驱动
驱动代码怎么读取设备树信息?
4.1.2 路径
arch/arm/boot/dts
4.1.3dts
- dtsi soc级
- dts 板级
- topeet_emmc_hdmi.dts
imx6ull-14x14-evk-emmc.dts
imx6ull-14x14-evk.dts
imx6ull.dtsi
4.1.4 dtc(device-tree-compiler 编译器)
- 编译
- 反编译
dtc -I dtb -O dts -o test001.dts topeet_emmc_hdmi.dtb
4.1.4dtb :Blob
4.2 根文件系统proc
根文件系统制作rcs
5.烧录调试
5.1调试模式V1
5.1.1原理
Uboot从板子emmc启动
内核、设备树、根文件系统从服务端(远程)
- tftp:远程下载内核、网络、设备树
- nfs:挂载网络根文件系统network file system
5.1.2 网络搭建
5.1.2.1硬件环境要求
- 板子网口2通过网线直接连接电脑
- 电脑没有网口 可以买一个网卡转usb
- 电脑有网口,但是用来连接网络了(不是WIFI上网)
也可以买一个网口转USB
5.1.2.2 tftp搭建
虚拟机Linux作为服务端
- cd ~
- mkdir tftpfile
- sudo chmod 777 tftpfile
- sudo apt-get install tftp-hpa tftpd-hpa
- sudo vim /etc/default/tftpd-hpa
修改为如下内容,具体路径根据自己实际情况
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/wfeng/tftpfile"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-l-c-s"
- sudo service tftpd-hpa restart
5.1.2.3 nfs搭建
1.下载
sudo apt-get install nfs-kernel-server rpcbind
2.创建文件夹
cd ~
mkdir nfs
- 修改文件
sudo vim /etc/exports
最后面添加
/home/ling/nfs *(rw,sync,no_root_squash)
具体添加内容 路径 根据自己的实际情况
wq保存退出
5. 重启nfs服务:
sudo /etc/init.d/nfs-kernel-server restart
5.1.2.4双网卡模式设置
5.1.2.4.1 Windows端
将与板子网线连接的电脑网口的网卡设置成静态IP
网线分别插在电脑网口和开发板网口上,开发板上电
-
找到网卡
-
双击点开设置IP地址
-
可以按照如图设置,设置完记得点确定
5.1.2.4.2 VMware虚拟机设置
-
虚拟机点编辑,然后点虚拟网络编辑器
-
点更改设置
-
点添加网络(我添加的是VMnet1,名字不重要)
-
把主机模式改为桥接模式
-
选择那会改为静态IP的网卡
5.1.2.4.3 Ubuntu设置
-
虚拟机名字处点右键,然后点设置
-
点添加
-
选择网络适配器
-
此时会出现一个新的网络适配器,选中,改为自定义,然后选择那会的虚拟网卡,我的是VMnet1
-
打开虚拟机终端,输入ifconfig,会看到两个网卡,如果没有就重启一下Ubuntu(和图片网卡名字不一致无所谓,第二个网卡没有IP地址)
-
打开设置
-
选择网络,找到第二个没有IP的网卡,点开开关,然后点设置(齿轮)
-
如果两个网卡的紫色开关不能同时打开,需要按照下图给两个网卡添加不同的Profile,具体添加方式见下一步
-
两个紫色开关可以同时打开的话,就忽略下图
-
选IPV4,再选manual,再添加IP信息
-
输入ifconfig
如图显示两张网卡
- 一个是DHCP动态获取,用于上网
- 一个是静态IP,用于与板子通信
ping
5.1.2.5板子uboot网络设置
- 板子连接串口,打开MobaXterm串口,115200
- 板子上电,在截图中数字归零之前按键盘任意按键,进入uboot设置
- 输入 printenv 可以查看uboot当前环境变量
- 修改网络相关环境变量
- 服务器IP,linux的IP
setenv serverip 192.168.31.200
- 网关
setenv gatewayip 192.168.31.1
- 开发板uboot的IP地址
setenv ipaddr 192.168.2.120
- 子网掩码
setenv netmask 255.255.255.0
- 设置网卡地址
setenv ethaddr 42:03:07:3B:15:5F
- 保存环境变量
saveenv
这一步一定要做,要保存,保存到了emmc中
6. 重启
reset
- 测试
互相ping
- 重启板子,重新进入uboot
- 插上网线,打开虚拟机
- ping 虚拟机和windows的IP,如图所示能ping通即可
显示 alive就是ping通了,,活着,,,
- 注意:用虚拟机和windows ping uboot 是不通的
也不是ping不通,是uboot代码里面没有ping回复机制,或者说没有相关代码 - 如果想恢复uboot默认环境变量
env default -a
saveenv
5.1.3 修改uboot引导方式
5.1.3.1 把kernel、设备树、根文件系统放在对应的文件夹
- tftffile 放内核和设备树
- zImage:linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/boot/zlmage
- topeet_emmc_hdmi.dtb:/arch/arm/boot/dts/topeet_emmc_hdmi.dtb
- nfs 放根文件系统
- filezila传输 :网盘文件rootfs.tar.bz2
- samba传输 :网盘文件rootfs.tar.bz2
解压 :tar -xvf rootfs.tar.bz2
5.1.3.2 进入uboot设置环境变量界面
- uboot前3秒内按任意键,进入uboot
- 修改bootcmd
setenv bootcmd 'tftp 80800000 zImage; tftp 83800000 topeet_emmc_hdmi.dtb; bootz 80800000 - 83800000'
下载内核 下载设备树 加载内核和设备树
3. 修改bootargs
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.31.200:/home/ling/nfs ip=192.168.31.120:192.168.31.200:192.168.31.1:255.255.255.0::eth0:off'
!!!上面的 /home/ling/nfs 不要复制啊!!!!!!,改成你自己的nfs路径哦
可以pwd看看自己的路径名
4, 保存到emmc
saveenv
- 重启
reset
5.1.3.3 出现nfs挂载失败问题(nfs版本问题)
解决方法
- Ubuntu打开文件
sudo vim /etc/default/nfs-kernel-server
- 末尾添加
RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog"
前面不要有#
3. 保存
wq!
- 重启nfs
sudo /etc/init.d/nfs-kernel-server restart
5.1.3.4 挂载成功后
- 用户名 root
- 密码 topeet
5.2烧写到emmc
5.2.1烧写软件的使用
5.2.1.1烧写要准备的
把要烧写的固件放在这个路径里,这个是必须的
下面这个路径是Windows的烧写工具路径,别搞错了
mfgtools_for_6ULL\Profiles\Linux\OS Firmware\files\linux
5.2.1.1固件包括
- Uboot文件
Uboot源码编译生成 uboot.imx - 内核文件
内核源码编译生成 zImage
路径arch/arm/boot - 设备树
内核源码编译生成 路径arch/arm/boot/dts
- topeet_emmc_4_3.dtb
- topeet_emmc_5_0.dtb
- topeet_emmc_7_0.dtb
- topeet_emmc_9_7.dtb
- topeet_emmc_10_1.dtb
- topeet_emmc_1024x600.dtb
- topeet_emmc_hdmi.dtb
- 根文件系统
5.2.2进入USB烧录模式
5.2.2.1把imx6ul板子拨码开关拨到USB烧录模式
5.2.2.2数据线连接到板子上标有OTG的USB口
另一端直接连接电脑USB口
5.2.2.3打开烧录软件mfgtools_for_6ULL
注意事项
- mfgtools_for_6ULL\Profiles\Linux\OS Firmware\files\linux里面的固件必须全
- 用右键管理员权限打开MfgTool2.exe
- 尽量关掉虚拟机
- 如果打不开,或者报错,去任务管理器关闭残余进程
5.2.2.4开发板上电
5.2.2.5看到烧录软件显示 符合 HID 标准的供应商定义设备后
点击start 开始烧录
5.2.2.6看到显示右图,代表烧录完成
5.2.2.7关闭软件先点Stop,再点Exit
5.2.3进入emmc启动模式
- 烧录完成后,开发板断电
- 拨码开关拨到 EMMC启动方式
- 数据线插到板子上标有 UART的USB口上
- 打开MobaXterm,选择对应串口,波特率115200
- 开发板上电
- 系统启动
用户名:root
密码:topeet
6.应用入门
6.1oled&mpu6050使用
- 硬件购买
- 0.96OLED屏幕
- 2.00mm转2.54mm母对母杜邦线
- 硬件接法
- 应用编译
arm-linux-gnueabihf-gcc app.c -o app -lm
- 驱动编译
内核模块
ko文件
- 单独编译
- 单独加载
insmod
rmmod
lsmod
- 放在网络文件系统里就可以
设备树的修改
iic地址
- 七位
- 八位
Z:\Linux\kernel\linux-imx-rel_imx_4.1.15_2.1.0_ga\arch\arm\boot\dts\imx6ull-14x14-evk.dts
mpu6050@68 {compatible = "mpu6050,INV_MPU6050";//interrupt-parent = <&gpio5>;//interrupts = <0 0>;reg = <0x68>;status = "okay";//position = <1>;};oled@3c {compatible = "i2c_oled";reg = <0x3c>;status = "okay";};
6.2应用源码分析
文件描述符
dmesg查看内核打印的相关信息
dmesg | grep 6050
6.3一切皆文件
6.3.1. 虚拟文件系统
虚拟文件系统提供了一种统一的接口,使得用户空间程序可以通过文件系统的方式来访问各种设备和资源
- 文件描述符
- open、close、read、write
6.3.2 简单文件读写测试
/*************************************************************************> File Name: test.c> Author: csgec> Mail: 12345678@qq.com > Created Time: 2025年04月10日 星期四 14时51分38秒************************************************************************/#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include<stdio.h>
int main(){int fd;char buff[]="iamlpy777\n";fd=open("./a.txt",O_RDWR|O_CREAT);if(fd<0){printf("can not open file");return fd;}write(fd,buff,sizeof(buff));memset(buff,'\0',sizeof(buff));lseek(fd,0,SEEK_SET);read(fd,buff,sizeof(buff));printf("buff:%s\n",buff);close(fd);return 0;
}
6.4自启动
6.4.1自启动修改文件
- /etc/init.d/rcS
- /etc/rc.local
- systemd
编写服务配置步骤
新建sh
创建服务
编辑服务
sudo gedit /etc/systemd/system/my_script.service
6.4.2绝对路径
相对路径
6.4.3后台执行
&
6.4.4异步通知
ctrl + c
kill -9 pid
-1SIGHUP 挂起信号 通常用于重新加载配置
-2SIGINT 中断信号(Ctrl+C) 终止前台进程
-9SIGKILL强制终止 立即终止,不可拦截
-15 SIGTERM默认终止信号(kill 的默认行为) 允许进程清理资源后退出
-19 SIGSTOP暂停进程(Ctrl+Z) 进程进入暂停状态,可恢复
7.驱动入门
7.1什么是驱动
7.1.1物理驱动
电机驱动
7.1.2软件驱动
框架
7.1.2.1应用层
7.1.2.2内核层
- 系统调用
- open
- read
- write
- ioctrl
- close
- 虚拟文件系统
- 驱动代码
- 字符设备驱动
- 网络设备驱动
- 块设备驱动
- 设备接口
7.1.2.3硬件层
各种硬件设备
7.2驱动的分类
7.2.1字符设备驱动
按字节流顺序访问
- 串口
- 鼠标键盘
- 摄像头
7.2.2网络设备驱动
- 基于TCP/IP协议
- 有线网卡(百兆、千兆、万兆)
- 无线网卡
- socket
7.2.3块设备驱动
按块随机访问
- 硬盘
- 存储卡
多个自己一块
7.3学驱动学的是什么
代码框架
内核模块三要素
- 入口
module_init:insmod - 出口
module_exit:rmmod - 许可证
MODULE_LICENSE(“GPL”);
开源协议
7.4MPU6050驱动流程
7.4.1 module_init(mpu6050_driver_init);
7.4.2 mpu6050_driver_init
7.4.3 i2c_add_driver(&mpu6050_driver);
i2c_register_driver(THIS_MODULE, driver)
7.4.4 mpu6050_driver
- .probe = mpu6050_probe
- .remove = mpu6050_remove
- .id_table = gtp_device_id
- .driver
- .name = “mpu6050”
- .owner = THIS_MODULE
- .of_match_table = mpu6050_of_match_table
{.compatible = “mpu6050,INV_MPU6050”},
7.4.5 mpu6050_probe
7.4.5.1分配设备号 alloc_chrdev_region(&mpu6050_devno, 0, DEV_CNT, DEV_NAME);
- 设备号
- 主设备号
- 次设备号
- 查看主次设备号
cd /dev/
ls -l
- 动态创建
- 静态创建
- /proc
- 内核数据的映射
- 系统信息查询接口:cat /proc/cpuinfo
-验证你注册的主设备号是否已经生效 cat /proc/devices - 查看中断号是否被注册 :cat /proc/interrupts
- 系统信息查询接口:cat /proc/meminfo
- /sys
7.4.5.2 初始化字符设备结构体cdev_init(&mpu6050_chr_dev, &mpu6050_chr_dev_fops);
7.4.5.2.1. mpu6050_chr_dev_fops
- .open = mpu6050_open 函数作用:打开设备时调用。
mpu6050_init # 进行MPU6050初始化
内部会调用:
i2c_write_mpu6050(mpu6050_client, PWR_MGMT_1, 0X00)
i2c_transfer(mpu6050_client->adapter, &send_msg, 1);
即:通过 I2C 向 MPU6050 写控制寄存器,通常是唤醒 MPU6050(PWR_MGMT_1 = 0x00)
- .read = mpu6050_read
函数作用:用户调用 read() 读取数据时执行。
流程如下
i2c_read_mpu6050(); // 发起 I2C 读取动作
i2c_transfer(mpu6050_client->adapter, mpu6050_msg, 2); // I2C 收发
copy_to_user(buf, mpu6050_result, cnt); // 将读取到的数据复制到用户空间
- mpu6050_release
释放设备,一般在 close() 时调用。
printk("\n mpu6050_release \n");
7.4.5.2.2绑定设备和fops结构体
fops:file_operations 的缩写,是 Linux 内核中字符设备驱动的一个核心结构体,用于定义用户空间调用设备文件时,内核该如何响应。
fops 是一个“函数指针表”,决定了 open()、read()、write() 等操作对应调用驱动中的哪个函数
7.4.5.3 添加设备cdev_add(&mpu6050_chr_dev, mpu6050_devno, DEV_CNT);
7.4.5.4创建设备类 class_create(THIS_MODULE, DEV_NAME);
7.4.5.5 创建设备节点device_create(class_mpu6050, NULL, mpu6050_devno, NULL, DEV_NAME)
7.4.6 module_exit(mpu6050_driver_exit)
i2c_del_driver(&mpu6050_driver)
7.5IOLED驱动流程
7.5.1模块载入入口module_init(oled_init)
7.5.2oled_init函数中的核心操作
i2c_add_driver(&oled_driver);
将 oled_driver 注册到 I2C 总线,系统会根据设备树或板级信息自动调用 .probe = oled_probe。
7.5.3 oled_driver结构体定义
.name = "oled",
.owner = THIS_MODULE,
.probe = oled_probe,
.remove = oled_remove,
.id_table = oled_id,
.of_match_table = oled_of_match_table,
这部分表明该驱动支持的设备匹配方式,包括设备树或设备 ID。
7.5.4oled_probe 函数中是驱动的核心逻辑:
字符设备注册流程
alloc_chrdev_region(&devid, 0, 1, "oled"); // 1. 分配设备号
cdev_init(&i2c_cdev, &oled_fops); // 2. 初始化字符设备,并绑定 fops
cdev_add(&i2c_cdev, devid, 1); // 3. 添加到内核
class_create(THIS_MODULE, "oled_class"); // 4. 创建类
device_create(...); // 5. 创建设备节点
oled_fops 是 file_operations 函数指针表:
struct file_operations oled_fops = {.open = oled_open,.write = oled_write,.release = oled_release,.unlocked_ioctl = oled_ioctl,
};
各个函数含义:
函数 | 作用 |
---|---|
oled_open | 初始化硬件,调用 oled_hw_init() ,内部通过 oled_write_cmd() 进行 I2C 配置 ,oled_clear() :oled_write_cmd/oled_write_data;oled_pos(0,0) :oled_write_cmd |
oled_write | 向设备写入数据,使用 copy_from_user() 获取用户数据,调用 OLED_ShowString() 显示字符串(内部调用 OLED_ShowChar() → oled_write_data() → i2c_transfer() ) |
oled_ioctl | 控制命令,调用 switch-case 来控制显示等功能 |
oled_release | 关闭设备,释放资源(或者打印日志) |
7.6模块卸载:
module_exit(oled_exit)
在卸载函数中调用:
i2c_del_driver(&oled_driver); // 卸载驱动
8.存储器分类
8.1寄存器
8.2RAM
断电之后,数据消失
- DRAM
- 电脑的内存条
- 靠电容存储信息
- 特点:容量大、成本低、需不断刷新(动态)
- SRAM
- CPU的多级缓存,cache
- 靠门电路来存储
- 特点:速度快、功耗低、但价格贵、容量小,不需要刷新
8.3ROM
断电之后,数据长久保存,主要用于固化程序,如 BIOS、启动程序等。
-
RAM
最早期,不能写 只能读 -
PROM
可编程只读存储器(Programmable ROM)
只能写入一次数据 -
EPROM
可编程可擦除只读存储器(Erasable Programmable Read Only Memory)
紫外线擦除
需整块擦除、再重新编程 -
EEPROM
带电可擦可编程只读存储器(EEPROM)
支持电擦除、反复写入,但速率较慢
-
NorFlash
一次可以读取一个字,每个bit都可以被寻址
优点:可直接执行代码(XIP),读速度快
缺点:写入速度慢、成本高 -
NandFlash
优点:容量大、价格便宜,广泛用于数据存储
应用:SSD、U盘、SD卡、eMMC
eMMC:= NandFlash + 控制器 + 标准封装接口(用于嵌入式系统)
分类 | 子类 | 特点或用途 |
---|---|---|
RAM | DRAM | 内存条,动态刷新,便宜 |
SRAM | CPU缓存,不刷新,贵但快 | |
ROM | PROM | 只能编程一次 |
EPROM | 紫外线擦除 | |
EEPROM | 电擦除,重复写入,广泛用于闪存 | |
NorFlash | XIP,读取快 | |
NandFlash | 写入快、便宜、容量大(SSD、U盘等) | |
eMMC | 嵌入式存储解决方案(手机、MCU等) |