ATSHA204A — Чтение Data и OTP зон памяти
На прошлом уроке мы провели блокировку Data и OTP зон памяти микросхемы ATSHA204A, тем самым завершив её окончательную настройку и блокировку. Теперь наша микросхема находится в рабочем «боевом» режиме работы со всеми заблокированными зонами памяти.
В этом режиме становятся доступны новые функции и возможности ATSHA204A, например, теперь мы можем читать информацию и данные из Data и OTP зон памяти, чего не могли делать до финальной блокировки (Lock Data).
В этой статье мы разберём приёмы и практические примеры кода чтения данных (ключей) из Data зоны ATSHA204A и информации (байтов) из OTP зоны нашей микросхемы.
Организация Data зоны
Для начала напомним вам организацию зоны данных (Data Zone) микросхемы ATSHA204A. Она состоит из 16-и слотов (блоков) памяти по 32 бита, каждый из которых, в свою очередь разбит на 8 смещений (offset) по 4 байта.
Таблица организации зоны данных:
Доступ к каждому слоту (блоку) регламентируется правилами, подробно описанными нами в предыдущих статьях, и ещё более подробно он описан в даташите ATSHA204A. Поскольку вы внимательно читали предыдущие статьи этого цикла о ATSHA204A, то хорошо знакомы с этими правилами и здесь мы не будем на этом останавливаться, а сразу приступим к созданию скетча чтения данных из Data зоны микросхемы ATSHA204A.
Чтение Data зоны
Теперь создадим скетч, который будет читать информацию (ключи) из зоны данных ATSHA204A. Всего зона данных содержит 16 ключей, каждый по 32 бита. На предыдущих занятиях мы записали все эти 16 ключей в память ATSHA204A, но поскольку зона данных не была заблокирована, то не смогли их прочитать и удостовериться в правильности произведённой записи. Напомним вам результат наших предыдущих действий:
Каждый слот содержит (должен содержать) ключи из байтов, соответствующих номеру самого слота. Это не имеет какого-то особого смысла, значения байтов выбраны просто для теста.
Далее сам код скетча чтения ключей из зоны данных ATSHA204A:
/* ATSHA204 Read Data */ #include <sha204_library.h> #define ATSHA204_PIN A3 byte bufTx[SHA204_CMD_SIZE_MAX]; byte bufRx[SHA204_RSP_SIZE_MAX]; byte slot = 1; byte retCode = 0; #define SLOT_LEN 32 byte bufRead[SLOT_LEN]; atsha204Class sha204(ATSHA204_PIN); void setup() { Serial.begin(115200); Serial.println("ATSHA204 Read Data start..."); for (byte i = 0; i < 16; i++) { readConf(i); } } // Print void printBuffer(byte* data, byte len) { for (size_t i = 0; i < len; i++) { if (data[i] < 16) {Serial.print('0');} Serial.print(data[i], HEX); if (i < len - 1) {Serial.print(' ');} } } void readConf(byte slt) { retCode = sha204.sha204m_execute(SHA204_READ, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG, slt << 3, 0, NULL, 0, NULL, 0, NULL, WRITE_COUNT_SHORT, bufTx, WRITE_RSP_SIZE, bufRx); for (byte i = 0; i < SLOT_LEN; i++) { bufRead[i] = bufRx[SHA204_BUFFER_POS_DATA + i]; } Serial.print(F("Slot ")); if (slt < 10) {Serial.print('0');} Serial.print(slt); Serial.print(F(": ")); printBuffer(bufRead, SLOT_LEN); Serial.print(' '); if (retCode) {Serial.println(F("Err"));} else {Serial.println(F("Ok"));} } void loop() { }
Чтение будет производиться слотами по 32 байта
#define SLOT_LEN 32 byte bufRead[SLOT_LEN];
и в цикле перебираются все 16 слотов доны данных.
for (byte i = 0; i < 16; i++) { readConf(i); }
Чтение и вывод информации осуществляются функцией readConf(), которой в качестве аргумента передаётся номер текущего слота.
void readConf(byte slt) { retCode = sha204.sha204m_execute(SHA204_READ, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG, slt << 3, 0, NULL, 0, NULL, 0, NULL, WRITE_COUNT_SHORT, bufTx, WRITE_RSP_SIZE, bufRx); for (byte i = 0; i < SLOT_LEN; i++) { bufRead[i] = bufRx[SHA204_BUFFER_POS_DATA + i]; } Serial.print(F("Slot ")); if (slt < 10) {Serial.print('0');} Serial.print(slt); Serial.print(F(": ")); printBuffer(bufRead, SLOT_LEN); Serial.print(' '); if (retCode) {Serial.println(F("Err"));} else {Serial.println(F("Ok"));} }
Само чтение из ATSHA204A осуществляется функцией sha204.sha204m_execute() с соответствующими параметрами.
retCode = sha204.sha204m_execute(SHA204_READ, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG, slt << 3, 0, NULL, 0, NULL, 0, NULL, WRITE_COUNT_SHORT, bufTx, WRITE_RSP_SIZE, bufRx);
Далее производится заполнение принимающего массива bufRead
for (byte i = 0; i < SLOT_LEN; i++) { bufRead[i] = bufRx[SHA204_BUFFER_POS_DATA + i]; }
И вывод информации в Serial.
Serial.print(F("Slot ")); if (slt < 10) {Serial.print('0');} Serial.print(slt); Serial.print(F(": ")); printBuffer(bufRead, SLOT_LEN); Serial.print(' '); if (retCode) {Serial.println(F("Err"));} else {Serial.println(F("Ok"));}
Вот результат работы нашего скетча:
Обратите внимание, что успешно завершилось чтение ключей только из слотов 8, 11 и 12. Это связано с настройками IsSecret конфигурационной зоны нашей микросхемы. Вот скриншот состояния конфигурационной зоны с отмеченными байтами конфигурации 8-го, 11-го и 12-го слотов:
Чтение OTP зоны
Теперь переходим к чтению данных из OTP зоны. Сначала таблица организации OTP зоны, которая состоит из 2-х блоков по 32 байта (или 16-и слотов по 4 байта). Читается и пишется эта зона также в соответствии с правилами описанными нами ранее в предыдущих статьях.
На предыдущих уроках мы записали 16 4-байтовых слотов в OTP зону памяти нашей микросхемы ATSHA204A, вот скриншот результата этой записи:
Здесь мы создадим скетч, который прочитает 4 байта из 8-го слота OTP зоны. Вот полный код скетча ATSHA204 Read OTP:
/* ATSHA204 Read OTP */ #include <sha204_library.h> #define ATSHA204_PIN A3 byte bufTx[SHA204_CMD_SIZE_MAX]; byte bufRx[SHA204_RSP_SIZE_MAX]; byte slot = 8; byte retCode = 0; #define SLOT_LEN 4 byte bufRead[SLOT_LEN]; atsha204Class sha204(ATSHA204_PIN); void setup() { Serial.begin(115200); Serial.println("ATSHA204 Read OTP start..."); readConf(slot); Serial.print(F("slot")); if (slot < 10) {Serial.print('0');} Serial.print(slot); Serial.print(F(": ")); printBuffer(bufRead, SLOT_LEN); Serial.println(); } // Print void printBuffer(byte* data, byte len) { for (size_t i = 0; i < len; i++) { if (data[i] < 16) {Serial.print('0');} Serial.print(data[i], HEX); if (i < len - 1) {Serial.print(' ');} } } byte addr(byte slt) { return slt * 4; } void readConf(byte slt) { retCode = sha204.sha204m_read(bufTx, bufRx, SHA204_ZONE_OTP, addr(slt)); if (retCode) {Serial.print(F("Error "));} else {Serial.print(F("Ok "));} bufRead[0] = bufRx[SHA204_BUFFER_POS_DATA + 0]; bufRead[1] = bufRx[SHA204_BUFFER_POS_DATA + 1]; bufRead[2] = bufRx[SHA204_BUFFER_POS_DATA + 2]; bufRead[3] = bufRx[SHA204_BUFFER_POS_DATA + 3]; } void loop() { }
Сначала мы определяем номер слота, с которым будем работать
byte slot = 8;
Затем определяем массив для заполнения байтами одного слота
#define SLOT_LEN 4 byte bufRead[SLOT_LEN];
Производим чтение слота.
void readConf(byte slt) { retCode = sha204.sha204m_read(bufTx, bufRx, SHA204_ZONE_OTP, addr(slt)); if (retCode) {Serial.print(F("Error "));} else {Serial.print(F("Ok "));} bufRead[0] = bufRx[SHA204_BUFFER_POS_DATA + 0]; bufRead[1] = bufRx[SHA204_BUFFER_POS_DATA + 1]; bufRead[2] = bufRx[SHA204_BUFFER_POS_DATA + 2]; bufRead[3] = bufRx[SHA204_BUFFER_POS_DATA + 3]; }
И выводим результат в Serial.
Serial.print(F("slot")); if (slot < 10) {Serial.print('0');} Serial.print(slot); Serial.print(F(": ")); printBuffer(bufRead, SLOT_LEN); Serial.println();
Вот результат работы нашего скетча:
Как и ожидалось, 8-й слот содержит 4 байта 0xEE.
Заключение
На этом уроке мы научились читать информацию из Data и OTP зон микросхемы ATSHA204A, на следующем уроке мы приступим к изучению функций ATSHA204A по работе с SHA-256 ключами и генерации хешей.
Ссылки по теме
ATSHA204 - Библиотека и примеры
ATSHA204A - Чтение зоны конфигурации 1
ATSHA204A - Чтение зоны конфигурации 2
ATSHA204A - Чтение зоны конфигурации 3
ATSHA204A - Запись конфигурации 1
ATSHA204A - Запись конфигурации 2
ATSHA204A - Запись конфигурации 3
ATSHA204A - Запись конфигурации 4
ATSHA204A - Работа в режиме Config Lock
ATSHA204A - Работа с зонами памяти
ATSHA204A - Аутентификация. Базовый блок
ATSHA204A - Аутентификация. Датчик
ATSHA204A - Криптография и команды
ATSHA204A - nRF24 аутентификация. База
ATSHA204A - nRF24 аутентификация. Датчик