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