參考文章:
Lin總線通信在STM32作為主機代碼以及從機程序
基于STM32的LIN總線的實現
STM32F0-LIN總線通訊程序代碼 主從調試OK
LIN協議通信DEMO及源碼剖析
前文已講解關于LIN幀代碼如何實現:【LIN】1.LIN通信實戰:幀收發全流程代碼實現
幀類型
在了解了網上的LIN代碼就會發現,所謂的LIN主機程序和從機程序大概是分為四個場景如下:
1. 主機:發送ID -> 從機:響應數據 -> 主機:接收數據
2. 從機:接收ID -> 發送數據
(這描述的是同一個過程,只是從主從兩個視角看)
-
LIN幀類型:無條件幀(Unconditional Frame)
-
過程詳解:
- 主機(Master):發送幀頭(Header)。這個Header里最關鍵的就是受保護的標識符(PID)。這個PID決定了哪個從機需要響應,以及這個幀的含義是什么(例如,0x30代表請求車速信號)。
- 從機(Slave):總線上所有從機都接收到了這個Header。每個從機都有自己的調度表(Schedule Table) 和信號處理程序,它們會檢查這個PID。
- 如果這個PID與自身某個發布(Publish) 任務的PID匹配(例如,車速傳感器從機被配置為對PID 0x30進行響應),則該從機負責回復。
- 從機(Slave):在規定的響應時間內,發送響應(Response),即數據場(1-8字節) + 校驗和場。
- 主機/其他從機(Master/Other Slaves):接收這個響應。主機或其他需要該數據的從機(配置為訂閱(Subscribe) 此PID的節點)會從數據場中解析出具體的信號(如車速值=50km/h)。
-
這是LIN總線最主要的數據廣播機制。
3. 主機:發送ID+數據 -> 從機:接收數據并處理
4. 從機:接收ID+數據 -> 處理數據
(這描述的也是同一個過程)
- LIN幀類型:這也是一種無條件幀,但數據流向是主機到從機。
- 過程詳解:
- 主機(Master):發送幀頭(Header) + 數據場(Data Field) + 校驗和場(Checksum)。注意:這里主機發送了完整的幀!
- 從機(Slave):所有從機接收整個幀。它們通過PID來判斷這個幀是發給誰的、是干什么的。
- 例如,主機發送一個PID為0x31的幀,數據場包含一個字節0x55,意思是“打開空調”。
- 配置為訂閱(Subscribe) PID 0x31的空調控制器從機,會識別這個PID,然后讀取數據場,解析出信號,并執行相應的操作(打開空調)。
- 響應問題:從機通常不會在總線上進行響應(ACK)。LIN協議沒有規定應用層必須應答。如果主機需要確認命令是否被執行,它必須在后續的調度中,再發起一個查詢幀(第一種方式),去讀取從機的某個狀態信號(例如,讀取空調開關狀態PID),來間接確認。
由此我們知道了,原來網上所說的主從機代碼指的是無條件幀,那么其它幀又是怎么用到的,下面從實際場景出發,了解LIN的5種幀
一、 LIN核心思想:主從結構與單線通信
LIN(Local Interconnect Network)是一種低成本、低速率的車載網絡協議,用于實現汽車中的分布式電子系統控制。
- 核心特點:
- 單線通信:僅使用一根信號線,極大降低了線束成本和復雜度。
- 主從結構:通信永遠由主節點(Master) 發起,從節點(Slave) 響應。從節點不能主動發送數據。
- 基于調度表:主節點內部有一個像“歌單”一樣的調度表,循環決定下一刻要發送哪個幀,保證了通信的有序性。
二、 五種關鍵“幀”與溝通機制
LIN的“幀”是通信的基本單元。一個完整的幀由幀頭(Header) 和響應(Response) 組成。幀頭由主節點發送,響應由從節點發送。
我們可以從三個維度來理解LIN的通信方式:幀類型、調度策略和標識符用途。
下面我們通過一個擴展的汽車車窗控制場景來詳細講解這五種方式是如何協同工作的。
場景角色:
- 主機(Master):車身控制模塊(BCM)。它是車門LIN總線的主控節點。
- 從機1(Slave 1):主駕駛車門開關模塊(內部有LIN芯片)。它負責報告開關狀態。
- 從機2(Slave 2):副駕駛車門控制模塊(內部有LIN芯片和電機驅動器,帶防夾功能)
- 診斷儀:維修設備(通過CAN網關連接)
1. 無條件幀 (Unconditional Frame) - 基石
這是LIN最常用、最基本的通信模式,用于周期性數據交換。
-
理論:主機發送幀頭(含PID),指定從機回復數據;或主機發送完整幀(含數據)向從機下達命令。
-
實踐(場景:正常控制):
- 步驟a (主機問,從機答):BCM發送幀頭
PID=0x21
(查詢開關狀態)。開關模塊(從機1)響應數據Data=0x02
(二進制00000010
,表示“副駕升起”按鈕被按下)。 - 步驟b (主機發命令):BCM解析后,發送一個完整幀:
PID=0x32
(控制副駕車窗) +Data=0x02
(命令:上升)。副駕模塊(從機2)接收并執行,不產生總線響應。 - 步驟c (主機確認):BCM發送幀頭
PID=0x33
(查詢車窗狀態)。副駕模塊響應Data=[50, 0x00]
(位置50%,狀態正常)。
- 步驟a (主機問,從機答):BCM發送幀頭
-
溝通方式:純粹的“發布-訂閱”模型。BCM“訂閱”了開關狀態,開關模塊“發布”該狀態。副駕模塊“訂閱”了控制命令,BCM“發布”該命令。
2. 事件觸發幀 (Event Triggered Frame) - 優化師
用于處理多個從機可能發生、但通常不會同時發生的事件,以節省帶寬。
- 理論:主機發送一個公共PID,多個從機被配置可響應它,但只有狀態發生變化的從機才會實際回復。若多個從機同時回復導致沖突,主機會退回到輪詢模式。
實踐(場景:防夾功能激活):
副駕車窗在上升過程中遇到障礙物,電機電流陡增,模塊檢測到阻力過大,判定為防夾事件。
- 傳統方式(低效):BCM需要不斷輪詢每個車門的狀態幀(
PID=0x33
,0x34
,0x35
…)來檢查是否有異常,即使大部分時間都沒有事件發生,這浪費了總線帶寬。 - 高效方式(事件觸發幀):BCM發送一個公共的詢問幀,誰有事誰回答。
過程如下:
- BCM 發送一個特殊的Header,其
PID=0x40
。這個PID在LDF中被定義為事件觸發幀,它對應著一組可能發生事件的從機狀態(比如,副駕車窗狀態、天窗狀態、尾門狀態等都屬于“事件源”)。 - 多個從機(副駕模塊、天窗模塊…)都配置為可以響應這個PID。
- 此時:
- 天窗模塊狀態無變化,它選擇保持沉默。
- 副駕模塊因為剛剛觸發了防夾功能,狀態發生了重要變化,它立刻在響應時隙內回復數據。它回復的數據就是它自身的狀態數據(例如
Data = [75, 0x01]
,位置75%,防夾觸發標志位為1)。
- BCM 接收到響應,解析后知道是副駕車窗發生了防夾,它可能會記錄事件、甚至讓儀表盤顯示一個警告提示。
沖突處理:如果極端情況下,副駕車窗和天窗同時發生事件并都回復,會導致總線沖突和校驗和錯誤。BCM檢測到錯誤后,就會退出事件觸發模式,轉而逐一發送每個從機專屬的PID(0x33
問副駕,0x34
問天窗…)來精確定位所有事件源。
3. 診斷幀 (Diagnostic Frame) - 外科醫生
用于執行點對點的深度訪問,如讀取故障碼、寫配置參數等。
- 理論:使用保留的專用PID(
0x3C
和0x3D
),遵循UDS等標準診斷服務格式,數據長度固定為8字節。
實踐(場景:讀取詳細故障數據):
車輛維修時,技師需要更詳細的信息,而不僅僅是“防夾觸發了”這個狀態位。他需要知道歷史故障碼、電機堵轉電流值等深層數據。這需要通過診斷幀來實現,這是一種點對點、高可靠性的通信。
過程如下:
- 診斷儀(通過CAN)向BCM發送一個診斷請求:“讀取副駕車窗控制模塊的故障碼(服務ID: 0x22)”。
- BCM 作為LIN總線的主機,充當了網關的角色。它將來自CAN的請求翻譯成LIN總線上的診斷幀。
- BCM 在LIN總線上發送一個Header,其
PID=0x3C
。這是一個專用的診斷請求標識符,所有從機都知道這個PID用于診斷。 - BCM 緊接著發送數據場(8字節),這8字節符合UDS(統一診斷服務)標準格式:
Byte 0
: 0x02 — 表示后續有效數據長度。Byte 1
: 0x22 — 服務ID,0x22
代表“按標識符讀數據”。Byte 2 & 3
: 0xF1 0x90 — 一個自定義的診斷標識符,代表“讀取第一個防夾事件的歷史數據”。- 剩余字節填充為0x00。
- 副駕模塊 識別到
PID=0x3C
是診斷請求,并且數據場中的標識符0xF190
是給自己的。它準備診斷響應數據。 - BCM 隨后再發送一個Header,其
PID=0x3D
。這是一個專用的診斷響應標識符。 - 副駕模塊 響應這個
0x3D
幀,回復8字節的診斷數據:Byte 0
: 0x04 — 后續有效數據長度。Byte 1
: 0x62 — 對0x22
請求的響應(0x22 + 0x40)。Byte 2 & 3
: 0xF1 0x90 — 回顯請求的標識符。Byte 4
: 0x05 — 故障碼,例如0x05
代表“防夾功能激活”。Byte 5
: 75 — 發生時的車窗位置(75%)。
- BCM 接收到響應后,再通過CAN總線轉發給診斷儀。技師就在診斷儀屏幕上看到了詳細的故障信息。
4. 偶發幀 (Sporadic Frame) - 調度策略
核心思想: 這是一種優化帶寬的高級調度策略。主機(Master)不會死板地周期性地發送每一個幀,而是只在確信該幀所攜帶的數據有可能會更新時,才在調度表中插入這個幀。
為什么需要它?
想象一下,車窗從完全關閉到完全打開需要5秒鐘。如果BCM以100ms的周期去查詢車窗位置(PID=0x33
),那么在5秒內會發送50次查詢,但回復的位置值可能只是從0, 2, 4, 6… 慢慢變到100。很多次查詢返回的數據變化極小,這是一種帶寬浪費。
“偶發”如何工作?
- 條件觸發:主機BCM知道,只有當你按下開關(
PID=0x21
有變化) 或者收到事件觸發幀(PID=0x40
報告了事件) 時,車窗位置才會開始快速變化。 - 動態插入:當BCM檢測到上述“觸發條件”時,它就會在接下來的幾個調度周期里,臨時、高頻地插入查詢車窗位置的幀(
PID=0x33
)。 - 停止查詢:當BCM發現位置數據在連續幾次查詢中不再變化(比如車窗已經到達目標位置),它就會停止發送這個查詢幀,從而節省出帶寬給其他任務。
場景舉例(優化后的調度):
- 常態(車窗靜止):BCM的調度表主要循環發送:
0x21
(問開關)、0x22
(問門鎖)… 它不發送0x33
(問車窗位置),因為位置沒變化,問了也是白問。 - 按下開關:BCM通過
0x21
得知用戶命令。 - 動態調整:BCM立即修改調度表,在未來5秒內,高頻循環:
0x21
->0x32
(發命令)->0x33
(問位置) ->0x21
->0x32
->0x33
… - 恢復常態:BCM通過
0x33
的響應發現位置已達到100%且不再變化,于是從調度表中移除0x33
,恢復到此前的低頻查詢模式。
所以,“偶發幀”不是一種新幀,它仍然是無條件幀,只是它的發送時機是“偶發的”、“有條件的”,而非周期性的。這是一種主機軟件的智能調度算法。
5. 保留幀 (Reserved Frame) - 標識符分類
核心思想: 這是指LIN協議規范中為未來用途預留的標識符(PID)。這些PID有特定的值,不能用于普通的無條件幀。
為什么需要它?
為了保障協議的擴展性和兼容性。LIN聯盟預先規定好哪些PID是留給未來新功能或特殊功能的,這樣所有廠商的芯片和軟件都會遵守這個規則,避免沖突。
常見保留幀:
- 主請求幀 (Master Request Frame):
PID = 0x3C
- 從響應幀 (Slave Response Frame):
PID = 0x3D
- 這兩個PID就是我們之前講的診斷幀的專用通道。它們被“保留”用于診斷目的。
- 其他保留范圍:協議還規定了其他一些范圍的PID值(例如0x30-0x31之間的某些值)也被保留,用戶不能自定義使用。
場景舉例:
當BCM需要與副駕模塊進行診斷通信時,它必須使用保留的PID:0x3C
和0x3D
。它不能自己定義一個比如PID=0x40
來做診斷,因為:
0x40
可能已經被你用作事件觸發幀了。- 副駕模塊的廠商是按照標準協議開發的,它的軟件只認
0x3C
和0x3D
是診斷幀。如果你用0x40
,它根本不會把它當成診斷請求來處理。
所以,“保留幀”指的是那些使用了保留PID的幀,這些幀用于特定目的(主要是診斷),普通應用層通信不能占用這些PID。
三、 總結與協作圖景
在真實的汽車網絡中,這五種方式絕非孤立工作,而是緊密協作,形成一個高效的整體。它們的關系如下圖所示:
為了更清晰地理解,我們可以用以下表格來總結所有這些概念在車窗控制場景中的具體體現:
概念分類 | 具體類型 | 目的 | 在車窗場景中的具體示例 |
---|---|---|---|
幀類型 | 無條件幀 | 基礎數據交換 | PID=0x21 (查詢開關狀態)PID=0x32 (發送升降命令)PID=0x33 (查詢車窗位置) |
事件觸發幀 | 高效處理多從機事件 | PID=0x40 (廣播查詢,誰有異常事件誰響應) | |
診斷幀 | 配置、診斷、讀故障碼 | 使用PID=0x3C (主請求)和0x3D (從響應)讀取詳細防夾故障碼 | |
調度策略 | 周期調度 | 固定時間間隔查詢 | 每100ms查詢一次開關狀態(PID=0x21 ) |
偶發調度 | 優化帶寬,動態查詢 | 僅在收到升降命令后,才臨時高頻查詢車窗位置(PID=0x33 ) | |
PID用途 | 自定義PID | 用于普通應用功能 | 0x21 , 0x32 , 0x33 , 0x40 等,由系統設計師定義 |
保留PID | 保證兼容和擴展 | 0x3C , 0x3D 等,協議規定只能用于診斷,不可另作他用 |
調度表(Schedule Table)
如果說LIN總線上的各種幀(無條件幀、事件觸發幀等)是樂手們演奏的音符,那么調度表就是主機(Master)手中的指揮棒和樂譜。它規定了在什么時間、由誰來演奏哪個音符,確保了整個LIN網絡通信的井然有序,避免沖突。
一、 調度表是什么?
調度表是主機節點(在我們的場景中就是BCM)內部的一個定時任務列表。它定義了:
- 發送順序:幀與幀之間的先后執行順序。
- 時間基準:每個幀或每一組幀之間的時間間隔(例如,每個幀槽
Frame Slot
的持續時間)。
它的本質是一個無限循環的“歌單”,主機CPU會嚴格按照這個歌單,周而復始地依次發送各個幀的Header,從而 orchestrate(協調)整個總線的通信。
二、 調度表里有什么?
一個調度表由多個調度表條目(Schedule Table Entry) 組成。每個條目至少包含兩樣東西:
- 要發送的幀:例如,發送PID為
0x21
的Header(查詢開關狀態)。 - 該幀的延遲時間:發送完當前幀后,等待多長時間再發送下一個幀。這個時間稱為幀時隙(Frame Slot)。
一個簡單的調度表示例(車窗控制基礎版):
調度表條目 | 幀的PID | 含義 | 幀時隙(例如:10ms) |
---|---|---|---|
1 | 0x21 | 查詢主駕開關狀態 | 2個時隙(20ms后發下一個) |
2 | 0x22 | 查詢門鎖狀態 | 3個時隙(30ms后發下一個) |
3 | 0x31 | 控制主駕車窗(命令幀) | 2個時隙(20ms后發下一個) |
4 | 0x32 | 控制副駕車窗(命令幀) | 3個時隙(30ms后發下一個) |
… | … | … | … |
注:幀時隙必須大于該幀完成整個通信(Header + 最大可能Response時間)所需的時間,并為從機的處理留出余量。
三、 調度表如何工作?動態調度與場景結合
調度表并非一成不變。一個優秀的主機程序會管理多個調度表,并根據當前車輛狀態在不同調度表之間切換,這就是“動態調度”的概念。結合我們的車窗場景:
1. 基礎調度表(正常狀態)
當車輛平穩運行,沒有緊急事件時,BCM使用一個周期性的基礎調度表。這個表就像背景音樂,持續循環,監控著基本狀態。
- 內容:主要包含高優先級的、需要持續監控的無條件幀。
PID=0x21
:頻繁查詢開關狀態(用戶隨時可能操作)。PID=0x22
:查詢門鎖狀態。PID=0x33
:以較低頻率查詢車窗位置(因為位置不會瞬間變化,無需高頻查詢,這是偶發幀調度思想的體現)。
- 特點:循環周期短,帶寬占用穩定。
2. 事件觸發調度(高效響應)
當BCM通過基礎調度表收到開關命令(PID=0x21
響應變化)或收到事件觸發幀(PID=0x40
)的報告時,它知道有“事情”發生了。
- 動作:BCM可能會臨時切換到一個更密集的調度表,或者在基礎調度表中動態插入幾個幀。
- 場景舉例(用戶按下開關):
- 基礎調度表中,
PID=0x21
的響應數據從0x00
變為0x02
(副駕升起)。 - BCM識別到這個變化,判定為“事件”。
- 在接下來的幾個循環中,BCM大幅提高
PID=0x32
(控制副駕車窗)和PID=0x33
(查詢副駕車窗位置)的發送頻率。 - 這就相當于指揮棒突然指揮某幾個樂手(副駕控制模塊)快速、密集地演奏一段solo,以實現車窗的平滑移動和實時位置監控。
- 當車窗到達目標位置后,BCM再切回基礎調度表。
- 基礎調度表中,
3. 診斷調度表(精準干預)
當診斷儀接入(例如,CAN網關轉發診斷請求給BCM),需要執行深度診斷時。
- 動作:BCM會暫停當前的調度表,立即切換到一個專為診斷服務的調度表。
- 場景舉例(讀取故障碼):
- BMC收到診斷請求。
- BCM中斷當前循環,切換到診斷調度表。這個表里只包含兩個條目:
- 發送
PID=0x3C
+ 8字節診斷請求數據。 - 等待一個幀時隙后,發送
PID=0x3D
的Header,準備接收從機的診斷響應。
- 發送
- 完成診斷通信后,BCM再切回之前的調度表,從中斷處繼續執行。
- 特點:優先級最高,實時響應,執行完即退出。