当前位置: 首页 > news >正文

ARM-Linux 完全入门

1.准备部分

1.1 虚拟机安装

  1. 准备VMware软件、ubuntu系统镜像
  2. 安装过程
  • VMware安装
    破解(自己百度破解码,多试几个网址,会有能用的)
  • Ubuntu安装
  1. 配置联网
    桥接
    虚拟机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命令行

  1. 打开终端 Ctrl+Alt+t
    • 一个窗口打开第二个 Ctrl+Shift+t
    • 新窗口打开第二个 Ctrl+Alt+t
  2. 字体放大 Ctrl+(+)
  3. 字体缩小 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 界面方式
  1. 点Ubuntu左下角菜单,选紫色的SoftWare&Updates 软件
  2. 点Download from 选择other
  3. 再选择C开头的china,然后点mirrors.aliyun.com,最后点Choose Server
  4. 进行密码验证 最后点close
  5. 然后点reload
  6. sudo apt update
  7. 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
  1. sudo apt-get install vsftpd
  2. sudo vim /etc/vsftpd.conf
    找到 #write_enable=YES
    把#删掉,然后保存
    在这里插入图片描述
  3. 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
  1. 打开文件管理器
    点击此电脑

  2. 选择映射网络驱动器
    在这里插入图片描述

  3. 添加
    \虚拟机IP地址\share
    eg:\192.168.31.169\share

  4. 输入用户名&密码

3.3.2.3 注意

如果连接不上,关闭Linux(sudo ufw disable)和Windows防火墙

3.3.3 scp

3.3.4 共享文件夹

4.系统编译

4.1 交叉编译器安装

  1. cd /usr/local
    sudo mkdir arm
    cd arm
  2. 把交叉编译工具链拷贝到/usr/local/arm文件夹(FTP)
    sudo chmod 777 arm
  3. 解压 sudo tar -vxf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz
  4. 环境变量修改
  • 查看环境变量
    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
  1. 重启sudo reboot
  2. 测试 arm-linux-gnueabihf-gcc -v
  3. 编译

4.2 Uboot

4.2.1综述

是一套裸机程序,可以理解为板子上电的初始化
Uboot的源代码,启动流程,都值得分析,面试会问

4.2.2 编译

  1. 安装编译必用工具
sudo apt-get install lzop  libncurses5-dev u-boot-tools
  1. 拷贝迅为Uboot源代码
cd ~
mkdir Linux
mkdir uboot
cd uboot

拷贝FTP

  1. 解压
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/
  1. 编译
    ./create.sh
sudo apt install make 

Makefile

  • .config
  • make menuconfig
  • Kconfig
  1. 生成文件
  • uboot.imx
  • uboot.bin

4.2.3流程

4.2.3.1汇编部分
  • 中断
  • 看门狗
  • cache
  • mmu
  1. 进入SVC模式
  2. 基本硬件初始化
  • 时钟
  • 串口
  • flash
  • 闪存
  1. 初始化堆栈
  2. 自搬移
  • 重定位
  • 内存运行块
    在这里插入图片描述
4.2.3.1C语言部分
  1. 初始化大部分硬件
  • 网卡
  • 屏幕
  • usb
  1. 把内核搬到内存

4.2.4Uboot源码简要分析

4.2.4.1汇编部分
  1. 跳转到reset
    arch/arm/lib/vectors.S
    在这里插入图片描述
  2. arch/arm/cpu/armv7/start.S
  • reset
    在这里插入图片描述

  • cpu_init_cp15 在这里插入图片描述

  • cpu_init_crit
    在这里插入图片描述

  1. arch/arm/cpu/armv7/lowlevel_init.S
    在这里插入图片描述

  2. arch/arm/lib/crt0.S
    在这里插入图片描述

4.2.4.1C语言部分
  1. common/board_f.c
    board_init_f
    在这里插入图片描述

  2. common/board_r.c
    board_init_r
    在这里插入图片描述
    run_main_loop
    在这里插入图片描述

  3. 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 编译过程

  1. 拷贝迅为kernel源代码
cd ~
cd Linux
mkdir kernel
cd kernel

拷贝 FTP

  1. 解压
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
  1. 编译
    ./create.sh
  2. 编译后自动生成的文件
  • arch/arm/boot
    image 非压缩文件
    zimage
    uimage
  • arch/arm/boot/dts 设备树

4.3.2 内核源码

  1. 各个文件都是什么意思
  2. 源码查看软件 Source Insight 4.0
  • 把解压完的内核源码从虚拟机拷贝到Windows
  • 新建Source Insight工程

4.3.3 编译脚本

  1. #!/bin/bash
    bash脚本
  2. make imx_v7_defconfig
  • arch\arm\configs
  • .config
  1. make uImage LOADADDR=0x10008000 -j16
  2. make modules
  3. 驱动编译的两种方式
  • 将驱动编译进内核:obj-y:yes内建
  • 将驱动编译进ko文件:obj-m:module模块
  1. make *.dtb

4.1 设备树

4.1.1功能

包含芯片&板子 外设信息
系统驱动会匹配设备树,匹配成功后加载驱动
驱动代码怎么读取设备树信息?

4.1.2 路径

arch/arm/boot/dts

4.1.3dts

  1. dtsi soc级
  2. dts 板级
  3. 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启动
内核、设备树、根文件系统从服务端(远程)

  1. tftp:远程下载内核、网络、设备树
  2. nfs:挂载网络根文件系统network file system

5.1.2 网络搭建

5.1.2.1硬件环境要求
  1. 板子网口2通过网线直接连接电脑
    在这里插入图片描述
  2. 电脑没有网口 可以买一个网卡转usb
    在这里插入图片描述
  3. 电脑有网口,但是用来连接网络了(不是WIFI上网)
    也可以买一个网口转USB
5.1.2.2 tftp搭建

虚拟机Linux作为服务端

  1. cd ~
  2. mkdir tftpfile
  3. sudo chmod 777 tftpfile
  4. sudo apt-get install tftp-hpa tftpd-hpa
  5. sudo vim /etc/default/tftpd-hpa
    修改为如下内容,具体路径根据自己实际情况
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/wfeng/tftpfile"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-l-c-s"
  1. sudo service tftpd-hpa restart
5.1.2.3 nfs搭建

1.下载

 sudo apt-get install nfs-kernel-server rpcbind

2.创建文件夹

cd ~ 
mkdir nfs
  1. 修改文件
 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
网线分别插在电脑网口和开发板网口上,开发板上电

  1. 找到网卡在这里插入图片描述

  2. 双击点开设置IP地址在这里插入图片描述

  3. 可以按照如图设置,设置完记得点确定在这里插入图片描述

5.1.2.4.2 VMware虚拟机设置
  1. 虚拟机点编辑,然后点虚拟网络编辑器在这里插入图片描述

  2. 点更改设置在这里插入图片描述

  3. 点添加网络(我添加的是VMnet1,名字不重要)在这里插入图片描述

  4. 把主机模式改为桥接模式在这里插入图片描述

  5. 选择那会改为静态IP的网卡

5.1.2.4.3 Ubuntu设置
  1. 虚拟机名字处点右键,然后点设置在这里插入图片描述

  2. 点添加在这里插入图片描述

  3. 选择网络适配器
    在这里插入图片描述

  4. 此时会出现一个新的网络适配器,选中,改为自定义,然后选择那会的虚拟网卡,我的是VMnet1在这里插入图片描述

  5. 打开虚拟机终端,输入ifconfig,会看到两个网卡,如果没有就重启一下Ubuntu(和图片网卡名字不一致无所谓,第二个网卡没有IP地址)在这里插入图片描述

  6. 打开设置在这里插入图片描述

  7. 选择网络,找到第二个没有IP的网卡,点开开关,然后点设置(齿轮)

  • 如果两个网卡的紫色开关不能同时打开,需要按照下图给两个网卡添加不同的Profile,具体添加方式见下一步
    在这里插入图片描述

  • 两个紫色开关可以同时打开的话,就忽略下图
    在这里插入图片描述

  1. 选IPV4,再选manual,再添加IP信息
    在这里插入图片描述

  2. 输入ifconfig
    如图显示两张网卡
    在这里插入图片描述

  • 一个是DHCP动态获取,用于上网
  • 一个是静态IP,用于与板子通信
    ping
5.1.2.5板子uboot网络设置
  1. 板子连接串口,打开MobaXterm串口,115200
  2. 板子上电,在截图中数字归零之前按键盘任意按键,进入uboot设置
  3. 输入 printenv 可以查看uboot当前环境变量
  4. 修改网络相关环境变量
  • 服务器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
  1. 保存环境变量
saveenv

这一步一定要做,要保存,保存到了emmc中
6. 重启

reset
  1. 测试
    互相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、设备树、根文件系统放在对应的文件夹
  1. 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
  1. nfs 放根文件系统
  • filezila传输 :网盘文件rootfs.tar.bz2
  • samba传输 :网盘文件rootfs.tar.bz2
    解压 :tar -xvf rootfs.tar.bz2
5.1.3.2 进入uboot设置环境变量界面
  1. uboot前3秒内按任意键,进入uboot
  2. 修改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
  1. 重启
reset
5.1.3.3 出现nfs挂载失败问题(nfs版本问题)

在这里插入图片描述
解决方法

  1. Ubuntu打开文件
sudo vim /etc/default/nfs-kernel-server
  1. 末尾添加
RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog"

前面不要有#
3. 保存

wq!
  1. 重启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固件包括
  1. Uboot文件
    Uboot源码编译生成 uboot.imx
  2. 内核文件
    内核源码编译生成 zImage
    路径arch/arm/boot
  3. 设备树
    内核源码编译生成 路径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
  1. 根文件系统

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启动模式

  1. 烧录完成后,开发板断电
  2. 拨码开关拨到 EMMC启动方式
    在这里插入图片描述
  3. 数据线插到板子上标有 UART的USB口上
  4. 打开MobaXterm,选择对应串口,波特率115200
  5. 开发板上电
  6. 系统启动
    用户名:root
    密码:topeet

6.应用入门

6.1oled&mpu6050使用

  1. 硬件购买
  • 0.96OLED屏幕
  • 2.00mm转2.54mm母对母杜邦线
  1. 硬件接法 在这里插入图片描述
    在这里插入图片描述
  2. 应用编译
arm-linux-gnueabihf-gcc app.c -o app -lm
  1. 驱动编译
    内核模块
    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内核层
  1. 系统调用
  • open
  • read
  • write
  • ioctrl
  • close
  1. 虚拟文件系统
  2. 驱动代码
  • 字符设备驱动
  • 网络设备驱动
  • 块设备驱动
  1. 设备接口
7.1.2.3硬件层

各种硬件设备

7.2驱动的分类

7.2.1字符设备驱动

按字节流顺序访问

  1. 串口
  2. 鼠标键盘
  3. 摄像头

7.2.2网络设备驱动

  1. 基于TCP/IP协议
  • 有线网卡(百兆、千兆、万兆)
  • 无线网卡
  1. socket

7.2.3块设备驱动

按块随机访问

  • 硬盘
  • 存储卡
    多个自己一块

7.3学驱动学的是什么

代码框架
内核模块三要素

  1. 入口
    module_init:insmod
  2. 出口
    module_exit:rmmod
  3. 许可证
    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

  1. .probe = mpu6050_probe
  2. .remove = mpu6050_remove
  3. .id_table = gtp_device_id
  4. .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);
  1. 设备号
  • 主设备号
  • 次设备号
  • 查看主次设备号
cd /dev/
ls -l
  • 动态创建
  • 静态创建
  1. /proc
  • 内核数据的映射
  • 系统信息查询接口:cat /proc/cpuinfo
    -验证你注册的主设备号是否已经生效 cat /proc/devices
  • 查看中断号是否被注册 :cat /proc/interrupts
  • 系统信息查询接口:cat /proc/meminfo
  1. /sys
7.4.5.2 初始化字符设备结构体cdev_init(&mpu6050_chr_dev, &mpu6050_chr_dev_fops);
7.4.5.2.1. mpu6050_chr_dev_fops
  1. .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)
在这里插入图片描述

  1. .read = mpu6050_read
    函数作用:用户调用 read() 读取数据时执行。
    流程如下
i2c_read_mpu6050(); // 发起 I2C 读取动作
i2c_transfer(mpu6050_client->adapter, mpu6050_msg, 2); // I2C 收发
copy_to_user(buf, mpu6050_result, cnt); // 将读取到的数据复制到用户空间

在这里插入图片描述

  1. 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

断电之后,数据消失

  1. DRAM
  • 电脑的内存条
  • 靠电容存储信息
  • 特点:容量大、成本低、需不断刷新(动态)
  1. SRAM
  • CPU的多级缓存,cache
  • 靠门电路来存储
  • 特点:速度快、功耗低、但价格贵、容量小,不需要刷新

8.3ROM

断电之后,数据长久保存,主要用于固化程序,如 BIOS、启动程序等。

  1. RAM
    最早期,不能写 只能读

  2. PROM
    可编程只读存储器(Programmable ROM)
    只能写入一次数据

  3. EPROM
    可编程可擦除只读存储器(Erasable Programmable Read Only Memory)
    紫外线擦除
    需整块擦除、再重新编程

  4. EEPROM
    带电可擦可编程只读存储器(EEPROM)
    支持电擦除、反复写入,但速率较慢

  • NorFlash
    一次可以读取一个字,每个bit都可以被寻址
    优点:可直接执行代码(XIP),读速度快
    缺点:写入速度慢、成本高

  • NandFlash
    优点:容量大、价格便宜,广泛用于数据存储
    应用:SSD、U盘、SD卡、eMMC
    eMMC:= NandFlash + 控制器 + 标准封装接口(用于嵌入式系统)

分类子类特点或用途
RAMDRAM内存条,动态刷新,便宜
SRAMCPU缓存,不刷新,贵但快
ROMPROM只能编程一次
EPROM紫外线擦除
EEPROM电擦除,重复写入,广泛用于闪存
NorFlashXIP,读取快
NandFlash写入快、便宜、容量大(SSD、U盘等)
eMMC嵌入式存储解决方案(手机、MCU等)

相关文章:

  • 基于朴素贝叶斯与 LSTM 的假新闻检测模型对比分析
  • 面试之 Java 新特性 一览表
  • 前端面经12 函数柯里化
  • 配置git从公网能访问-基于frp
  • 项目复习(2)
  • C语言:gcc 如何调用 Win32 打开文件对话框 ?
  • BERT 进阶:Albert 模型详解与实战
  • RFID系统:技术解析与应用全景
  • MATLAB学习笔记(七):MATLAB建模城市的雨季防洪排污的问题
  • Pandas 掌握Matplotlib基础绘图①
  • Redis——持久化
  • 单细胞转录组(1)
  • 嵌入式培训之数据结构学习(五)栈与队列
  • 手撕I2C和SPI协议实现
  • 机器学习回归预测中预处理的特征工程
  • 数据结构与算法——双向链表
  • QT调用Halcon查询所有摄像头名称
  • 基于 Python 的界面程序复现:标准干涉槽型设计计算及仿真
  • UE 材质基础 第一天
  • WPS JS宏实现去掉文档中的所有空行
  • 当“诈骗诱饵”盯上短剧
  • 茅台总经理到访五粮液:面对白酒行业周期性调整,需要团结一心的合力
  • 广西鹿寨一水文站“倒刺扶手”存安全隐患,官方通报处理情况
  • 著名文博专家吴远明因交通事故离世,享年75岁
  • 国际金价下跌,中概股多数上涨,穆迪下调美国主权信用评级
  • 习近平就乌拉圭前总统穆希卡逝世向乌拉圭总统奥尔西致唁电