目錄
一、Buildroot
1.1介紹
????????文件系統
? ? ? ? 1.一個完整的操作系統需要包含大量的文件
? ? ? ? 2.在嵌入式開發中目前應用最廣泛的文件系統制作工具就是 buildroot,busybox
? ? ? ? 3.buildroot 制作文件系統(了解)
二、雜項驅動編程
1.1 驅動編程做的內容
2.2 特點
2.3 設備號
2.4 相關 API
????????雜項設備注冊
????????雜項設備注銷
三、GPIO 子系統
3.1 介紹
3.2 GPIO 號
3.3 相關 API
????????GPIO 號的申請
????????GPIO 輸出方向的設置
????????GPIO 電平的設置
????????GPIO 的釋放
四、文件接口
一、Buildroot
1.1介紹
????????環境搭建過程,是根據板子官方的《用戶手冊》/《快速入門手冊》
????????環境搭建中不可避免的要遇到問題:
????????1、給售后打電話 ????????2、百度/看板子官方的論壇 ????????3、憑經驗
????????文件系統
? ? ? ? 1.一個完整的操作系統需要包含大量的文件
????????????????例如:Linux 系統
????????????????????????etc:環境配置文件
????????????????????????lib:庫文件
????????????????????????bin:二進制文件 --- 里面是各種各樣的可執行程序 --- 系統的部分指令 ls
????????????????????????sbin:管理員用戶可以執行的一部分指令 reboot
????????????????????????dev:設備文件 等
????????????????這些系統必要的文件中有大量的子文件/目錄,而我們是無法完全掌握每個文件的具體內容 ,所以文件系統的制作是需要依靠工具的
????????????????每個系統的文件,大體相同,局部不同
????????????????????????不同:系統中集成的庫
????????????????????????相同:可以依賴文件系統制作工具完成
? ? ? ? 2.在嵌入式開發中目前應用最廣泛的文件系統制作工具就是 buildroot,busybox
????????????????busybox 是比較早的文件系統制作工具
????????????????????????制作的文件系統非常純粹 --- 基本沒有其它的工具庫,都需要開發者自己去移植,移植庫需要不停的編譯和復制
????????????????buildroot 給開發者降低了開發難度
????????????????buildroot 的文件系統其實也是由 busybox 做的,buildroot 集成了 busybox
????????????????buildroot 的優勢在于可以直接通過 make menuconfig 圖形化配置界面,去勾選系統中想要加入的庫文件,在編譯過程中會直接將勾選的庫加入到文件系統中,不需要移植,不需要適配
????????????????buildroot 的缺點:編譯時間非常長,并且對硬件要求比較高
????????????????buildroot 第一次編譯的時間在 8~12 小時
????????????????大部分編譯對運行內存要求極高 --- 是為了 build(編譯)庫
????????????????內核數越多,相對來說,編譯的越快
????????????????一部分庫他需要去外國網站下載,速度極慢,慢到一定程度,就斷開了 ?????????
???????????????
?????????????????dl 文件就是影響編譯比較大的因素,其中放的都是下載的各種各樣的庫
????????????????buildroot 是開源的,也可以去下載,將已經下載好的 dl 庫放進來,可以大大減少 buildroot 的編譯時間
? ? ? ? 3.buildroot 制作文件系統(了解)
????????????????如果制作了后,后續需要重新編譯 SDK,自己做的文件系統僅僅可以讓系統運行起來,還需要加各種庫,需要百度搜索,在制作之前先把 SDK 生成的配置文件給刪除
????????????????解決 Buildroot 終端沒有終端提示符,在板子的終端
vi /etc/profile.d/myprofile.shPS1='[\u@\h]:\w$ 'export PS1保存退出
????????????????文件系統復原
????????????????gedit device/rockchip/rk3588/BoardConfig-rk3588s-evb1-lp4x-v10-yyt.mk
export RK_CFG_BUILDR00T=rockchip_rk3588s
然后
./build.sh lunch 選5
然后
./build.sh
????????????????LVGL 在 buildroot 中選中
????????????????????????嵌入式設備才支持 LVGL 生成的可執行程序
????????????????????????除此之外還需要勾選 SDL 庫
????????????????????????這樣 buildroot 生成的文件系統中的交叉編譯工具才支持編譯 LVGL 的程序,這個交叉編譯工具的名字帶有 build
二、雜項驅動編程
1.1 驅動編程做的內容
????????Linux 下一切皆文件
????????每一個硬件設備在系統中用文件體現的:
????????????????鍵盤(/dev/input/event1)和鼠標(/dev/input/event2)
????????驅動開發就是將硬件設備 --- 描述在系統中
????????????????例如:讓一個 LED 燈用文件控制 --- 本質依然是 GPIO 操作
????????????????????????上系統之后,無法直接使用 GPIO
????????????????????????在系統中只能通過文件間接控制
????????????????將硬件設備變成一個文件
????????????????通過操作文件去操作這個設備
????????????????????????通過 open、read、write、close 實現不同的操作
????????????????????????例如:可以通過 open 文件接口去開燈
????????????????????????? ? ? ? ? ?通過 close 文件接口去關燈
????????????????用單片機直接可以控制 GPIO,也可以開關燈
????????那么我為什么要做驅動:MCU 性能有限 --- 可以做控制,但是做 UI 一類的比較弱
????????在字符設備驅動開發中有三種開發方法 :雜項????????Linux2.6????????經典
????????????????演示:雜項和 Linux2.6
2.2 特點
????????1、最簡單的驅動開發方法
????????2、唯一 一個可以主動生成設備文件的驅動開發方法
????????3、主設備號固定為 10,次設備號 0~255
????????????????雜項設備開發方法的缺點:設備文件有限
????????????????0~255 還有系統占用的次設備號
????????設備文件:
????????????????字符設備文件開發 ---??
????????????????塊設備文件開發
????????????????網絡設備文件開發
2.3 設備號
????????設備號是區分不同設備文件的唯一標識
????????完整的設備號總共 32 位
????????????????高 12 位是主設備號,低 20 位是次設備號
????????區分不同文件的唯一標識 --- 節點號
????????????????節點號的查看 --- ls -i
?? ? ? ?目前做的是字符設備編程 --- 會向系統注冊設備文件
????????開發方放的學習就像 MCU 的不同編程方式
????????????????寄存器:代碼及其簡潔,代碼可讀性極差
????????????????庫函數:好記,代碼可讀性強,代碼篇幅過長
????????????????HAL 庫:通過點一點就可以完成簡單的功能 ---?代碼必須寫在固定位置
????????學習的是一個框架 --- 固化的流程
????????雜項的開發流程
????????????????1、搭建驅動開發的框架
????????????????2、雜項設備注冊
????????????????3、雜項核心結構體定義
????????????????4、雜項核心結構體填充
????????????????5、雜項設備注銷
2.4 相關 API
????????關鍵字:misc
????????頭文件:#include <linux/miscdevice.h>
????????雜項設備注冊
????????函數原型? ? ? ??
????????????????int misc_register(struct miscdevice *misc)
????????函數參數
struct miscdevice
{//雜項驅動編程的核心結構體int minor; //次級的 --- 次設備號//次設備號會被占用 --- 255 表示隨機分配const char *name; //生成的設備文件名//這個名字會出現在/dev/下const struct file_operations *fops; //文件接口核心結構體{使用的頭文件是:#include <linux/fs.h>對于當前情況下,只需要填寫一個內容struct module *owner; //在內核中固定填寫 THIS_MODULE}}
????????函數返回值
????????????????成功返回 0,失敗返回負的錯誤碼
????????雜項設備注銷
????????函數原型
????????????????void misc_deregister(struct miscdevice *misc)
????????函數參數
????????????????同上
三、GPIO 子系統
3.1 介紹
????????GPIO 子系統是 Linux 內核中用于管理通用輸入輸出(GPIO)引腳的核心框架,提
供標準化的 API 接口以簡化硬件操作。它通過抽象硬件細節,允許開發者通過設備樹
配置和驅動接口控制引腳方向、電平讀寫及中斷功能,并與 Pinctrl 子系統協同完成引
腳復用與配置。
????????用于控制 GPIO
????????四個 LED 燈:核心板有兩個,底板有兩個,蜂鳴器在底板
????????兩個用戶按鍵:在底板
????????哪個板子就看哪個板子的原理圖(核心板、底板)
????????LED1 對應的是 --- GPIO0_D0 ????????????????????????????????LED2 對應的是 --- GPIO1_D5
????????GPIO 子系統使用的主要是 GPIO 號
3.2 GPIO 號
????????GPIO 號在瑞芯微系列的芯片(RK,RV rockchip)中是可以根據 GPIO 的名字算出來的
????????GPIO 號的計算方式
????????GPIOx_yz? :x*32+(y-A)*8+z
????????????????例如:LED1 的 GPIO0_D0?????????0*32+(D-A)*8+0 = 3*8 = 24
????????????????????????????????????????????????????????????????????????GPIO1_D5 → 1*32+(D-A)*8+5 = 61
????????GPIO 的使用過程
????????GPIO 號的申請
????????GPIO 輸出方向的設置
????????GPIO 電平的設置
????????GPIO 的釋放
3.3 相關 API
????????關鍵字:gpio
????????頭文件:#include <linux/gpio.h>
????????GPIO 號的申請
????????函數原型
????????????????int gpio_request(unsigned int gpio, const char *label)
????????函數參數
????????????????gpio:要申請 GPIO 的 GPIO 號
????????????????label:是一個標簽,不要重復,給個字符串就行
????????函數返回值
????????????????成功返回 0,失敗返回負數
????????GPIO 輸出方向的設置
????????函數原型
????????????????int gpio_direction_output(unsigned int gpio, int value)
????????函數參數
????????????????gpio:要設置的 GPIO 號
????????????????value:初始電平
????????????????????????1 高電平
????????????????????????0 低電平
????????函數返回值
????????????????成功返回 0,失敗返回負數
????????GPIO 電平的設置
????????函數原型
????????????????void gpio_set_value(unsigned int gpio, int value)
????????函數參數
????????????????gpio:要設置的 GPIO 號
????????????????value:設置電平值
????????GPIO 的釋放
????????函數原型? ? ? ??????????
????????????????void gpio_free(unsigned gpio)
????????函數參數
????????????????gpio:要釋放的 GPIO 號
四、文件接口
????????用戶直接操作的是系統,系統會通過文件接口(open,close 等)和內核的文件接口(重新定義 struct file_operations 結構體中的文件指針),完成控制硬件設備
struct file_operations {int (*open) (struct inode *, struct file *)int (*release) (struct inode *, struct file *)}
????????struct inode --- 在系統中調用 open 文件接口其實本質上是調用內核的(*open)接口,這個結構體中存放了應用層文件的信息 --- 其中就有設備號 --- 在多節點會用到
????????struct file --- 在多節點會用到,更多的時候這個結構體會作為形參作為實參傳入另外一個函數中
????????注意 :
????????????????在加載函數中,先申請的資源,在卸載函數中,后釋放
????????????????先申請的資源有可能會讓后申請的資源使用,在使用過程中被釋放可能會導致內核錯誤