iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
自我挑戰組

韌體工程師的不只 0x10 個問題系列 第 16

Day 16 - 硬體資源配置常見的坑

  • 分享至 

  • xImage
  •  

這篇文章的主題比較瑣碎,我們將一同探討幾個在嵌入式系統中,有關硬體資源配置要留意的細節。

位元數寫死

現在要令一個無號整數變數為 0,寫法如下:

unsigned int zero = 0;

這個 0 代表所有位元都是 0,也就是 0000 0000 0000 0000,那如果要寫出它的補數(也就是位元通通反轉),可以怎麼寫呢?

補數不就是 1111 1111 1111 1111,而每個 1111 都是十六進制的 F,那這樣寫不就得了?

unsigned int compzero = 0xFFFF;

看起來很合理,對吧?然而,這是在 16 位元的電腦有效,同樣的 compzero 如果放到 32 位元、甚至 64 位元的電腦上,會變成什麼呢?

32 位元電腦:

    0000 0000 0000 0000 1111 1111 1111 1111
= 0x  0    0    0    0    F    F    F    F

64 位元電腦:

    0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111
= 0x  0    0    0    0    0    0    0    0    0    0    0    0    F    F    F    F

但期待的數值其實是不管多少位元,通通都要變成 1,而不是前面還補上了 0

直接用指定數量的 F 寫死會導致該數隨電腦位元數不同而改變其代表的值,因此最好的方法應該是直接說要反轉這個 0 的每個位元,如下:

unsigned int compzero = ~0;

這個 compzero 不管放在多少位元的電腦上,都代表 0 的補數,也就是每個位元都是 1

記憶體管理

在嵌入式系統中,偶有從堆積(heap)中動態分發記憶體的可能,但這些操作可能引發下列三種問題:

記憶體碎片化 Memory Fragmentation

包含「外碎片(external fragmentation)」與「內碎片(internal fragmentation)」。

外碎片指的是空閒的記憶體零碎而不連續,例如以下記憶體空間:

已被佔用打 X:  XX  XXX    X   XX
記憶體空間  :____ ____ ____ ____

上面的記憶體空間共有 16 個單位、其中 8 個被佔用,表面上還有另外 8 個單位可以用。

然而,如果有某項工作要求配置 5 個單位的連續的記憶體空間,在這個範例中是找不到對應資源的,因為連續的空閒記憶體最長只有 3 個單位。

內碎片指的是已被使用的記憶體空間浪費,例如系統為某項工作配置 4 個單位的記憶體空間,但實際上只要用到 1 單位,那多出來的 3 個單位就是內碎片。

V    <- 實際上只用到一個單位,剩下三個浪費掉的稱為內碎片
____ <- 一共配置四個單位的記憶體空間給某項工作

變數生命週期 Variable Life Cycle

講的是給某變數用 malloc() 配置記憶體空間後,未在使用完畢、不再需要用到該變數時用 free() 把記憶體空間釋放出來,造成可用的記憶體空間逐漸減少,稱為「記憶體洩漏(memory leak)」問題。

垃圾回收 Garbage Collection

在比較高階的語言會有「垃圾回收」機制,由系統自己尋找不再使用的變數、把其佔據的空間收回來。

這樣做的好處是不用手動做 free(),但垃圾回收時機並不可測,可能導致短暫的停頓或延遲,造成系統不穩定。例如無人機飛行時,如果在某個不可預期的時間點進行垃圾回收,就會有一小段時間出現無人機無法處理飛行任務,造成飛行不穩定、甚至墜毀。

參考資料

  1. 韌體工程師的0x10個問題

上一篇
Day 15:無窮迴圈
下一篇
Day 17 - 執行緒超入門
系列文
韌體工程師的不只 0x10 個問題19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言