EEPROM

和 RAM 不同,EEPROM 提供在系統斷電後仍能儲存資料的空間 (就像顆小硬碟)。透過使用 Arduino 的 EEPROM 函式庫開發者可以讀寫 LinkIt 7697 上虛擬 (*) 的 EEPROM,且此 EEPROM 總容量大小為 1KB

(*) LinkIt 7697 的非揮發性儲存媒介只有 serial flash、並沒有 EEPROM。但為了相容於 Arduino 開發環境,透過使用 LinkIt SDK 裡的 NVDM (Non-Volatile Data Management) 模組模擬出一顆具有 1KB 大小的 EEPROM。

NVDM 所管理的總空間為 64KB,而這個空間由 LFlash 與 EEPROM 兩個函式庫共同分享使用。也就是說,如果開發者將 EEPROM 的 1KB 空間都使用完畢,那麼 LFlash 就只剩下 64 - 1 = 63KB 可以使用。反之,若開發者完全不使用 EEPROM,那麼 LFlash 就可以使用 NVDM 完整的 64KB 儲存空間。

使用方法

在使用 EEPROM APIs 前,須先加入相關的 header file:

#include <EEPROM.h>

存取 EEPROM 會使用到下列六個 APIs:

  • length()

  • read()

  • write()

  • update()

  • get()

  • put()

基本操作

若要查詢 EEPROM 的總空間大小,可呼叫 EEPROM.length(),在 LinkIt 7697 上它的回傳值會是 1024 (也就是 1KB)。

若要進行單一位元組的存取,可以使用 EEPROM.read()EEPROM.write()EEPROM.update() 等 API。這些函式的原型宣告如下:

uint8_t read(int idx);
void write(int idx, uint8_t val);
void update(int idx, uint8_t val);

API 參數定義為:

  • idx:要讀寫的位元組的位置。有效的位置範圍為 0 ~ EEPROM.length() - 1。

  • val:要寫入 EEPROM 的資料。

由於 flash 記憶體有最大寫入次數的物理限制,因此不建議對 flash 空間進行頻繁的寫入操作造成使用壽命下降。為了改善這個狀況,可以使用 .update() API 取代 .write() API 進行寫入。因為 .update() 會在每次寫入前,會先檢查該位置的資料是否與欲寫入的資料相同,若不相同才會真的觸發 flash 寫入。反之,若該位置的資料已經與欲寫入的資料相同,則 .update() 就不會觸發 flash 寫入。

相對的,若使用 .write() 進行寫入,則不會檢查欲寫入位置的資料為何,一律都會觸發 flash 寫入操作。

使用 [] 運算子進行存取

除了呼叫 API 之外,也可以使用 [] 運算子存取 EEPROM 如以下範例:

// read the byte from address 88 and store it to the 'data' variable
uint8_t data = EEPROM[88];
// write a byte (the value is 97) to address 76
EEPROM[76] = 97;
// increase the value in address 2 by 1
EEPROM[2]++;

多位元組存取

讀寫 EEPROM 時除了一次讀寫一個位元組,EEPROM 函式庫亦提供了 .get().put() 這兩個讓開發者可以同時存取多位元組的 API:

template<typename T> T &get(int idx, T &t);
template<typename T> const T &put(int idx, const T &t);

API 參數定義如下:

  • idx:要讀寫資料的起始位置。

  • t:用來儲存要讀出或寫入 EEPROM 的位元組的資料結構。

以下是使用 .get().put() 的操作範例:

// define the data type
typedef struct
{
  int id;
  float value;
  char ch;
} data_t;
 
data_t input, output;
int address = 76;
 
// init the values for input
input.id = 10;
input.value = 123.456f;
input.ch = 'c';
 
// store the input data to the EEPROM
put(address, &input);
// after the input is stored, we can read it back from the same address
get(address, &output);

在這個範例裡,透過呼叫 .put() 將一多位元組的資料結構 (data_t) 寫入 EEPROM。寫入後,可再透過 .get() 讀出來。讀出來的結果應該和寫入的內容是一致的。

若要參考更多範例,請點選 Arduino IDE 裡的 Files / Examples / EEPROM 選單,裡面提供了更多不同的 EEPROM 應用範例。

Last updated