AUTOSAR MCAL MCU模塊解析
1. 簡介
MCU驅(qū)動程序提供微控制器初始化,掉電功能,復(fù)位和微控制器其他MCAL軟件模塊所需的特定功能的服務(wù)(這里主要指那些公共寄存器的設(shè)置)。需要注意的是,啟動代碼和用于升級的Bootloader是不在AUTOSAR負(fù)責(zé)范圍內(nèi)的,啟動代碼是特定于MCU的(不同MCU的啟動代碼都不一樣,見下章節(jié)),如下圖所示。
?
MCU驅(qū)動程序直接訪問微控制器硬件,位于微控制器抽象層(MCAL)中。
MCU驅(qū)動包含如下功能:
初始化MCU時鐘,PLL,時鐘預(yù)分頻器和MCU時鐘分配。
RAM初始化。
低功耗模式激活。
MCU復(fù)位。
提供從硬件獲取復(fù)位原因的服務(wù)/API。
通常,在AUTOSAR標(biāo)準(zhǔn)中,不強(qiáng)制激活和配置MCU低功耗模式。
啟用/禁用ECU/MCU電源也不是MCU驅(qū)動程序的任務(wù)。這將由上層管理模塊來處理。
配置內(nèi)容如下圖所示:
2. 啟動代碼
MCU初始化函數(shù)執(zhí)行前,必須先執(zhí)行一些MCU的基本初始化。通常這些特殊的初始化代碼我們叫啟動代碼。
MCU的啟動代碼應(yīng)該在上電以及任何單片機(jī)復(fù)位源復(fù)位以后執(zhí)行。它通常只執(zhí)行那些非常基本的和微控制器的一些特殊要求的初始化代碼,并且應(yīng)保持簡短,因為這個時候MCU時鐘和PLL尚未初始化。
如果執(zhí)行太臃腫的代碼肯定會影響效率,而汽車?yán)锩鎸ο到y(tǒng)啟動時間有比較高的要求。
通常啟動代碼應(yīng)涵蓋那些沒有在MCU模塊服務(wù)以及其他MCAL驅(qū)動里面包含的功能。以下總結(jié)了啟動代碼中將包含的基本功能。該列表僅做參考,因為某些功能可能并非在所有MCU中都支持,或者某些特殊功能未涵蓋。
啟動代碼應(yīng)初始化中斷和陷阱向量表的基地址。這些基地址可通過配置參數(shù)或鏈接器/定位器的設(shè)置提供。
啟動代碼將初始化用戶堆棧指針。用戶堆棧指針基地址和堆棧大小。同上,這些信息可通過配置參數(shù)或鏈接器/定位器設(shè)置提供。
如果MCU支持上下文保存操作,則啟動代碼應(yīng)初始化用于上下文保存操作的內(nèi)存。連續(xù)上下文保存操作的最大數(shù)量/大小通過配置參數(shù)或鏈接器/定位器設(shè)置提供。
啟動代碼應(yīng)確保在MCAL看門狗驅(qū)動程序初始化之前看門狗不溢出。例如,你可以通過增加看門狗服務(wù)時間或直接關(guān)閉看門狗(如果可以的話)來完成。
如果MCU支持用于數(shù)據(jù)和/或代碼的高速緩存,則應(yīng)在啟動代碼中對其進(jìn)行初始化和啟用。
啟動代碼應(yīng)針對內(nèi)部存儲器初始化MCU的特定功能,例如,存儲器/內(nèi)存保護(hù)。
如果使用外部存儲器,則應(yīng)在啟動代碼中初始化相應(yīng)存儲器。啟動代碼應(yīng)準(zhǔn)備好根據(jù)代碼位置的不同支持不同的內(nèi)存配置。從外部/內(nèi)部存儲器執(zhí)行代碼時,應(yīng)考慮不同的配置選項。不同存儲器的設(shè)置應(yīng)作為配置參數(shù)提供給啟動代碼。
在啟動代碼中,應(yīng)執(zhí)行MCU時鐘系統(tǒng)的默認(rèn)初始化,包括全局時鐘預(yù)分頻器。
如果MCU支持,啟動代碼應(yīng)啟用特殊功能寄存器(SFR)的保護(hù)機(jī)制。
啟動代碼將初始化所有必要的一次性寫入類型寄存器。如果某些寄存器被多個驅(qū)動程序共有,并且這些寄存器我們只希望寫入一次,而不是每個驅(qū)動程序初始化的時候都去寫一次,這種情況下也非常推薦將這些寄存器放在啟動代碼里執(zhí)行。
啟動代碼應(yīng)初始化最小數(shù)量的RAM,以便正確執(zhí)行MCU驅(qū)動程序服務(wù)和這些服務(wù)的調(diào)用方。
如果支持及需要使用,你還應(yīng)該初始化好安全校驗?zāi)K,比如CRC校驗,以免發(fā)生位錯誤。
注意:啟動代碼取決于ECU和MCU。 規(guī)范的詳細(xì)信息將在MCU的設(shè)計規(guī)范中進(jìn)行描述。
3. 重要概念及API詳解
3.1 復(fù)位
MCU驅(qū)動提供軟件觸發(fā)硬件復(fù)位的服務(wù),但不是任何用戶都可以使用該服務(wù),只有那些經(jīng)過授權(quán)的用戶才能調(diào)用該復(fù)位服務(wù)。
在一個ECU中,可能會有多種原因?qū)е聫?fù)位,在不同的應(yīng)用場景中,每次MCU重新初始化后可能需要知道具體的復(fù)位原因,如果硬件支持復(fù)位源查詢功能,則MCU驅(qū)動也提供獲取上一次復(fù)位原因的服務(wù)。
3.2 時鐘
MCU驅(qū)動提供使能及設(shè)置MCU時鐘的服務(wù)。比如:CPU時鐘,外設(shè)時鐘,時鐘分頻器,時鐘倍頻器等相關(guān)設(shè)置。MCU模塊還為其他BSW模塊提供必備的時鐘參考點(diǎn)(McuClockReferencePoint)。需要在MCU里面激活并配置好相關(guān)模塊的時鐘參考源。
3.3 模式
MCU驅(qū)動提供激活MCU節(jié)能模式的服務(wù),也就是我們平時說的低功耗模式。這些服務(wù)通常是直接訪問并操作MCU硬件寄存器。現(xiàn)在很多芯片對節(jié)能模式還劃分了很多等級,支持多個不同等級模式,那么需要根據(jù)你的項目需求在MCU模塊里面配置好你需要使用的模式。
在典型運(yùn)用中,ECU運(yùn)行期間,MCU低功耗模式的進(jìn)入或退出可能會頻繁切換,在這種情況下,任何一個MCAL模塊的激活喚醒都會執(zhí)行喚醒動作。
配置節(jié)能模式通常會影響到PLL,內(nèi)部晶振,CPU時鐘,外設(shè)時鐘,內(nèi)核時鐘等。
MCU的正常模式激活或電源切斷由上層負(fù)責(zé)。
某些MCU喚醒只能通過硬件復(fù)位來實現(xiàn)。
3.4 Mcu_Init
在Mcu_Init函數(shù)執(zhí)行后,那些配置數(shù)據(jù)才允許被相關(guān)函數(shù)訪問和使用,比如Mcu_InitRamSection。總的來說,MCU初始化函數(shù)對寄存器的操作需符合以下條款:
對于某些寄存器硬件只允許使用一種場景,那些這些寄存器由實現(xiàn)相關(guān)功能的模塊負(fù)責(zé)。這里標(biāo)準(zhǔn)原文不大好理解,簡單解釋就是,比如那些外設(shè)控制寄存器(SPI,ADC等等),通常這種寄存器只屬于該外設(shè)(與其他模塊沒任何關(guān)系),那么很顯然這些寄存器有相關(guān)外設(shè)來負(fù)責(zé)(SPI,ADC…)。
假如某個寄存器會影響多個硬件模塊,并且該寄存器不屬于I/O寄存器,則MCU模塊負(fù)責(zé)(如果屬于I/O模塊,由PORT模塊負(fù)責(zé))。
對于某些寄存器只能寫一次,這種寄存器由啟動代碼負(fù)責(zé)(在前文相關(guān)章節(jié)已經(jīng)提及)。
所有其他在前面未被提及類型的寄存器都由啟動代碼負(fù)責(zé)。
3.5 Mcu_InitRamSection
該函數(shù)負(fù)責(zé)從指定起始地址開始寫入指定總長度的指定默認(rèn)值,每次寫入長度也是配置指定的。共涉及下列配置信息:
McuRamSectionBaseAddress :指定起始地址
McuRamSectionSize :指定寫入總長度
McuRamDefaultValue :指定寫入默認(rèn)值
McuRamSectionWriteSize :指定每次寫入長度
該函數(shù)必須在Mcu_Init函數(shù)執(zhí)行后才能被調(diào)用。
3.6 Mcu_InitClock
該函數(shù)負(fù)責(zé)初始化PLL及其他配置的外設(shè)時鐘等。該函數(shù)執(zhí)行完后立馬退出,不會等PLL鎖相/穩(wěn)定(Locked)再退出,所以通常在該函數(shù)調(diào)用后需要用戶自行調(diào)用Mcu_GetPllStatus接口判斷時鐘是否已鎖相/穩(wěn)定。必須在Mcu_Init函數(shù)后調(diào)用。該函數(shù)是否有效受McuInitClock開關(guān)管控。
3.7 Mcu_DistributePllClock
該函數(shù)只有在McuNoPll設(shè)置為FALSE時才有效。該函數(shù)負(fù)責(zé)分發(fā)PLL時鐘,并釋放當(dāng)前的時鐘源(通常為內(nèi)部晶振)。
MCU從上電到時鐘初始化這段時間會使用默認(rèn)時鐘(芯片內(nèi)部自帶),所以當(dāng)新的時鐘PLL鎖相/穩(wěn)定后,需要釋放這個默認(rèn)時鐘。
只有在調(diào)用Mcu_GetPllStatus函數(shù)判斷PLL時鐘鎖相/穩(wěn)定后(Locked)才能調(diào)用該函數(shù)。如果PLL沒有鎖相/穩(wěn)定就調(diào)用,它會立即返回錯誤。
3.8 Mcu_GetResetReason
如果硬件支持查詢獲取復(fù)位原因,則該函數(shù)返回實際復(fù)位原因;如果硬件不支持,則返回值固定為上電復(fù)位(MCU_POWER_ON_RESET)。如果該函數(shù)在Mcu_Init函數(shù)之前調(diào)用,則返回未定義復(fù)位源(MCU_RESET_UNDEFINED)。
當(dāng)復(fù)位原因被讀出后,用戶需要保證復(fù)位源被清除掉,以防止獲取到多個復(fù)位原因。當(dāng)多次調(diào)用該函數(shù),每次返回結(jié)果應(yīng)該是一樣的。這意味著什么呢?也就是說軟件層面有一個管理機(jī)制,在保證多次調(diào)用返回相同結(jié)果的同時又得清理掉相應(yīng)的硬件復(fù)位源標(biāo)記。
3.9 Mcu_SetMode
該函數(shù)假定在調(diào)用它之前已經(jīng)禁用了所有中斷。它會保證不會丟掉喚醒中斷事件,通常通過后述方式來實現(xiàn)的,在真正設(shè)置掉電模式之前去檢查有沒有相關(guān)喚醒中斷處于pending狀態(tài),以此來保證不會丟掉喚醒中斷。
? ? ? ?責(zé)任編輯:tzh
評論