③、靜態模式
④、其他疑問
模仿stm32驅動開發實驗中,主要是在.s檔案中新增了清除.bss段資料(未初始化的資料段)的**。在.**件下對時鐘,io暫存器組的基位址進行巨集定義,並構造了對應的結構體(注意暫存器位址的連續性),最後將各個外設的暫存器組基位址強轉為對應的結構體指標並進行巨集定義,這樣在主函式中就能像stm32暫存器版本一樣使用結構體進行編寫了。下面是乙個簡單的例子:
#define ccm_base (0x020c4000)
//定義外設暫存器組基位址
typedef
struct
//暫存器結構體定義
ccm_type;
#define ccm ((ccm_type *)ccm_base)
//外設指標
進行bsp工程管理,目的是為了模組化整理**,將同一屬性的檔案存放在同一目錄裡面。具體步驟如下:
1、新建所需資料夾,將同一屬性的檔案存放在相應檔案中。
2、在不同驅動檔案下編寫驅動**。(相當於stm32中乙個外設有乙個.h和乙個.c檔案,它們存放在乙個資料夾裡面)
3、根據編寫的新驅動檔案,修改main.c的內容
這裡可能會出現呼叫標頭檔案報錯的問題,需要在工作區新建.vscode目錄,然後開啟c/c++配置器,.vscode目錄下會生成乙個c_cpp_properties.json的檔案,開啟,根據以下格式,寫出所有帶有標頭檔案的目錄。
makefile的編寫是這次實驗裡最重要的內容,可以通用於上述格式的**,以後的實驗只需要修改其中的小部分內容即可。先上**,再具體說明:
cross_compile ?= arm-linux-gnueabihf- # 變數定義
target ?= ledc
cc :=
$(cross_compile)
gcc
ld :=
$(cross_compile)
ldobjcopy :=
$(cross_compile)
objcopy
objdump :=
$(cross_compile)
objdump
incudirs := imx6u \ #包含有.**件的目錄
bsp/clk \
bsp/delay \
bsp/led
srcdirs := project \ #包含有.s,.c檔案的目錄
bsp/clk \
bsp/delay \
bsp/led
include :=
$(patsubst %, -i %, $(incudirs)
)#呼叫patsubst函式在所有.**件前+-i
sfiles :=
$(foreach dir, $(srcdirs)
, $(wildcard $(dir)
/*.s))
#呼叫foreach函式儲存目錄下的所有.s檔案,在變數中用到萬用字元要加wildcard
cfiles :=
$(foreach dir, $(srcdirs)
, $(wildcard $(dir)
/*.c))
#呼叫foreach函式儲存目錄下的所有.c檔案
sfilendir :=
$(notdir $(sfiles)
)#去除所有.s檔案路徑,只保留檔名
cfilendir :=
$(notdir $(cfiles)
)#去除所有.c檔案路徑,只保留檔名
sobjs :=
$(patsubst %, obj/%, $(sfilendir:.s=.o)
)#將檔案中所有的.s替換為.o並放在放在obj目錄下(屬於變數的高階用法)
cobjs :=
$(patsubst %, obj/%, $(cfilendir:.c=.o)
)#將檔案中所有的.c替換為.o並放在放在obj目錄下
objs :=
$(sobjs)
$(cobjs)
#將所有待鏈結檔案放在同乙個變數中
vpath :=
$(srcdirs)
#指定搜尋目錄,編譯.s,.c檔案是會在srcdirs中尋找
.phony:clean #指定偽目標clean
$(target)
.bin :
$(objs)
#生成bin檔案和反彙編檔案
$(ld)
-timx6u.lds -o $(target)
.elf $^
$(objcopy)
-o binary -s $(target)
.elf $@
$(objdump)
-d -m arm $(target)
.elf >
$(target)
.dis
$(sobjs)
: obj/%.o : %.s #使用了靜態模式
$(cc)
-wall -nostdlib -c -o2 $(include)
-o $@ $<
$(cobjs)
: obj/%.o : %.c
$(cc)
-wall -nostdlib -c -o2 $(include)
-o $@ $<
clean: #清除檔案
rm -rf $(target)
.elf $(target)
.dis $(target)
.bin $(objs)
patsubsst函式(模式字串替換函式)
基本格式$(patsubst 「pattern」,「replacement」,「text」)
查詢test中的單次是否符合模式pattern,如果匹配的話,則以replacement替換。pattern可以包括萬用字元「%」,表示任意長度的字串。如果replacement中也包含「%」,那麼,replacement中的這個「%」將是pattern中的那個「%」所代表的字串。
(個人理解:該處函式中的pattern僅為%,代表該變數中的所有檔案,替換為obj/%,相當於在所有檔案前加上了obj/。text只會替換掉pattern部分,其他部分不會改變,可以具體操作嘗試一下。)
foreach函式(迴圈函式)
基本格式$(foreach 「var」,「list」,「text」)
這個函式的意思是,把引數list中的單詞逐一取出放到引數var所指定的變數中,然後再執行text所包含的表示式。每一次text會返回乙個字串,迴圈過程中,text的所返回的每個字串會以空格分隔,最後當整個迴圈結束時,text所返回的每個字串所組成的整個字串(以空格分隔)將會是foreach函式的返回值。
所以,var最好是乙個變數名,list可以是乙個表示式,而text中一般會使用var這個引數來依次列舉list中的單詞。
notdir和dir函式
這兩個函式非常容易理解,notdir是去除檔案前目錄的顯示,dir是在檔案前顯示目錄。
: :
…targets定義了一系列的目標檔案,可以有萬用字元。是目標的乙個集合。
target-parrtern是指明了targets的模式,也就是目標集模式。
prereq-parrterns是目標的依賴模式,它對target-parrtern形成的模式再進行一次依賴目標的定義。(具體參考《跟我一起寫makefile》中的靜態模式)
1、在.h所屬的目錄前加上-i ,是為了將目錄新增到搜尋路徑中。
2、偽目標的作用是防止目錄中定義了相同名稱的檔案。
正點原子Mini Linux UART串列埠簡單介紹
二 部分例程 uart,也就是非同步序列收發器,使用uart與外界相連最少只要三條線 txd 傳送 rxd 接收 和gnd 地線 uart串列埠的介面電平有ttl和rs 232兩種,在正電原子的這款mini linux開發板上有ch340晶元,可以實現usb和串列埠ttl訊號之間的轉換,這裡用到的是...
(正點原子例程)wifi實驗(7 16)
正點原子wifi實驗分析 fatfs檔案系統分為三個層 應用層 fatfs模組 fats模組提供底層介面驅動層。1.應用層只需要呼叫fats提供的介面函式,如f open f read f write和f close等。2.fatfs模組提供的是ff.c和ff.h.除非有必要,一般情況下只需要直接包...
正點原子ucosIII學習筆記(一)
最近又開了新坑,在學過stm32後,我選擇去學學嵌入式作業系統,就從ucosiii開始好了。我看的是正點原子ucosiii的課程。第一節主要是介紹了下裸機跑程式和加作業系統跑程式的區別 裸機的話,乙個程式可分為前端和後端。後端就是乙個大迴圈,通過乙個死迴圈,不斷的呼叫hadeware裡函式的api,...