前言:想要對OSD下手已經不是頭一次了,前幾次都淺嘗輒止。一個是能力不夠,BetaFlight的代碼體系太龐大了,看不懂也摘不出來。
這次要做一款帶osd功能的接收機(用在遙控車上),所以又來打飛控程序主意。
參考代碼:betaflight-3.3.1
OSD疊加芯片:AT7456E 【可以在立創商城中搜索PDF的文檔】
Betaflight中有關于常用飛控型號的圖片,經過查看可以知道大多數飛控使用的OSD芯片為AT7456E。
飛控板子一般不會留下SWD接口給予調試。所以想要拿飛控板進行開發AT7456的話可以我之前發布的一篇文章進行燒錄。
下面是AT7456部分的電路圖。可以看到使用SPI與之通訊不需要額外的控制引腳。
MAX7456和AT7456的不同之處:
AT7456預裝512的字符, AT7456E有兩頁。MAX只有一頁。
AT通過CA【8】來翻頁,MAX用不到CA【8】。所以后面可以通過CA【8】寄存器來區分AT和MAX7456
解析過程:
=======================================
新版本的bf源代碼看起來不夠直觀,因為要適配很多平臺所以,看起來有點繞。
下面分析使用的版本為betaflight-3.3.1??梢缘絞ithub-bf下載歷史版本。
上述文件是OSD框架文件。這里沒有具體的硬件層操作,是將底層操作函數封裝成一個結構體。然后通過對結構體的調用,來實現對OSD芯片的操作。
【記住這里的幾個結構體的名字】等下會看到。
struct displayPortVTable_s; typedef struct displayPort_s { const struct displayPortVTable_s *vTable; xxxxx... } displayPort_t; typedef struct displayPortVTable_s { xxxxx... } displayPortVTable_t; typedef struct displayPortProfile_s { xxxxx... } displayPortProfile_t;
這里可以把結構體理解為一個類,這個類擁有描述自己參數,以及操作OSD的函數可以調用。像是Python中的Class。后面的程序會將結構體作為參數來傳遞。
========================================================================
通過上述文件:OSD顯示程序的調用是這里實現的,以60Hz的頻率調用 osdSlaveUpdate函數,相當于在后臺loop這個函數,以實現osd刷新功能。
進入【osdSlaveUpdate】函數 來到下面文件【osd_slave.c】
可以看到實際是調用的【displayDrawScreen(osdDisplayPort);】函數。
然后看一下這個文件主要做什么:
主要就三個函數:
一、Init初始化函數,osd初始化階段要做的事情。
displayWrite(osdDisplayPort, 13, 6, "OSD");
可以看出主要是通過displayWrite函數進行顯示。
二、check函數、暫時不關心
三、osdSlaveUpdate就是之前說的后臺Loop函數。用于程序運行過程中的刷新
從這個文件中就可以看出,所有的操作都是對displayPort_t結構體的實例化的操作。
接下來我們看看,初始化函數中傳入的實際參數是誰。
void osdSlaveInit(displayPort_t *osdDisplayPortToUse)
通過全局搜索:
是下面函數的返回值 給了init初始化函數。繼續進入函數內部查看
osdDisplayPort = max7456DisplayPortInit(vcdProfile());
【displayport_max7456.c】
【max7456.c】再進入max7456Init函數看一下:
可以看出這里是對硬件進行配置。很多操作都是針對硬件的了??蚱饋淼某绦蛑杏幸徊糠质菍π酒M行區分。
// Detect device type by writing and reading CA[8] bit at CMAL[6]. // Do this at half the speed for safety. spiSetDivisor(MAX7456_SPI_INSTANCE, MAX7456_SPI_CLK * 2); max7456Send(MAX7456ADD_CMAL, (1 << 6)); // CA[8] bit if (max7456Send(MAX7456ADD_CMAL|MAX7456ADD_READ, 0xff) & (1 << 6)) { max7456DeviceType = MAX7456_DEVICE_TYPE_AT; } else { max7456DeviceType = MAX7456_DEVICE_TYPE_MAX; }
通過對CA8寄存器的讀寫來判斷當前使用的那款芯片。
先對上述的幾個文件進行整理分析:
到此,對bf固件中osd部分代碼應該有一點點了解了。其實其他部分應該也是這樣看的。還剩下具體的硬件操作函數,我還沒有看完,正好篇幅挺長了,主要是截圖多??赐杲又鴮懀赐甏m.....