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