logo
+7 (495) 997-37-74
Москва, ул.Международная, 15

ATSHA204A — Запись зоны OTP

В прошлой статье мы научились записывать ключи в зону данных (Data Zone) ATSHA204A, в этой статье мы научимся записывать данные в OTP (One Time Programmable) зону этой микросхемы.

Как вы помните, OTP зона состоит 64-х байт (512 бит) и используется для хранения данных для чтения или одноразовой установки. До блокировки зоны OTP (наше состояние на данный момент) биты могут быть свободно записаны с использованием стандартной процедуры записи.

После блокировки зон данных и OTP (Lock Data), информация из OTP зоны памяти микросхемы ATSHA204A может быть считана и изменена согласно логики работы этой зоны.

Доступ к OTP зоне

OTP зона разбита на 2 слота (блока) по 32 байта, которые в свою очередь делятся на «смещения» (offsets) по 4 байта. Вот таблица из даташита, которая описывает организацию слотов OTP зоны и доступ к ним в зависимости от режима.

Обращение к данным внутри зоны памяти на чтение и запись происходит в нотации Block-Offset. Обращение это двухбайтовое, где старший байт всегда равен нулю, а младший формируется в зависимости от зоны.

В даташите также регламентируются дополнительные правила и ограничения работы с блоками (слотами) памяти OTP зоны микросхемы ATSHA204A.

Вот подробная таблица слотов (blocks) и смещений (offsets) OTP зоны памяти ATSHA204A. Значения по умолчанию всех байтов этой зоны равны 0xFF, то есть все биты выставлены в 1.

Таблица доступа к OTP зоне:

Запись данных в OTP зону

Теперь давайте создадим скетч, который будет записывать данные в OTP зону микросхемы ATSHA204A. Условия задачи: нужно создать скетч, который будет записывать 4 байта данных в OTP зону ATSHA204A по смещению (offset) 0. Сама микросхема ATSHA204A находится в состоянии заблокированной конфигурационной зоны и разблокированной Data зоны.

В практической работе и создании ваших проектов вам может понадобиться записать в OTP зону не 4, а например, 1 байт, но тут нужно помнить, что доступ к OTP зоне невозможен блоками менее 4-х байт, поэтому вам в любом случае придётся записывать сразу минимум 4 байта (по соответствующему offset смещению).

Сначала полный код скетча ATSHA204 OTP Zone Write, потом подробный разбор его работы.

/* 
  ATSHA204 OTP Zone Write
*/

#include <sha204_library.h>

#define ATSHA204_PIN A3

byte bufTx[SHA204_CMD_SIZE_MAX];
byte bufRx[SHA204_RSP_SIZE_MAX];

#define BUF_WRITE_LEN 4
byte bufWrite[] = {0xEE,0xEE,0xEE,0xEE};

atsha204Class sha204(ATSHA204_PIN);


void setup() {
  Serial.begin(115200);
  Serial.println(F("ATSHA204 OTP Zone Write..."));

  Serial.print(F("Write: "));
  printBuffer(bufWrite, BUF_WRITE_LEN);
  Serial.println();

  writeOtp(0);
}

// 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(' ');}
  }
}

// Write

void writeOtp(byte slt) {
  byte retCode = sha204.sha204m_execute(SHA204_WRITE,
                                        SHA204_ZONE_OTP | SHA204_ZONE_COUNT_FLAG, slt,
                                        4, bufWrite,
                                        0, NULL,
                                        0, NULL,
                                        WRITE_COUNT_SHORT, bufTx,
                                        WRITE_RSP_SIZE,    bufRx);
  if (retCode) {Serial.println(F("Write Error"));}
          else {Serial.println(F("Write Ok"));}
}

void loop() {

}

Вначале мы объявляем 4-байтовый массив и заполняем его тестовыми значениями 0xEE. Это те данные, которые мы хотим записать в OTP зону.

#define BUF_WRITE_LEN 4
byte bufWrite[] = {0xEE,0xEE,0xEE,0xEE};

Затем, для контроля, мы выводим в Serial данные, которые хотим записать в OTP зону.

  Serial.print(F("Write: "));
  printBuffer(bufWrite, BUF_WRITE_LEN);
  Serial.println();

И производим процедуру записи, передавая в качестве аргумента функции writeOtp() значение смещения (offset) равное нулю.

  writeOtp(0);

Саму запись осуществляет функция sha204.sha204m_execute(), с соответствующими параметрами, заданными в качестве аргументов.

void writeOtp(byte slt) {
  byte retCode = sha204.sha204m_execute(SHA204_WRITE,
                                        SHA204_ZONE_OTP | SHA204_ZONE_COUNT_FLAG, slt,
                                        4, bufWrite,
                                        0, NULL,
                                        0, NULL,
                                        WRITE_COUNT_SHORT, bufTx,
                                        WRITE_RSP_SIZE,    bufRx);
  if (retCode) {Serial.println(F("Write Error"));}
          else {Serial.println(F("Write Ok"));}
}

Вот результат работы нашего скетча:

Тут есть один тонкий момент: значения байтов выводятся только для визуального контроля, судить об успешности результата записи данных в OTP зону мы можем только косвенным образом, по коду возврата функции sha204.sha204m_execute().

Реально прочитать записанные данные и убедиться в их корректности мы сможем только после блокировки Lock Data.

Запись всей OTP зоны

Теперь усложним нашу задачу и создадим скетч, который записывает не частично, а сразу всю 64-байтовую OTP зону микросхемы ATSHA204A. Полный код скетча ATSHA204 OTP Zone Writes:

/* 
  ATSHA204 OTP Zone Writes
*/

#include <sha204_library.h>

#define ATSHA204_PIN A3

byte bufTx[SHA204_CMD_SIZE_MAX];
byte bufRx[SHA204_RSP_SIZE_MAX];

#define SLOT_LEN 4
byte bufWrite[16][4] = {
  {0x00,0x01,0x02,0x03},
  {0x04,0x05,0x06,0x07},
  {0x08,0x09,0x0A,0x0B},
  {0x0C,0x0D,0x0E,0x0F},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
};

atsha204Class sha204(ATSHA204_PIN);


void setup() {
  Serial.begin(115200);
  Serial.println(F("ATSHA204 OTP Zone Writes..."));

  for (byte i = 0; i < 16; i++) {
    writeOtp(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(' ');}
  }
}

// Write

void writeOtp(byte slt) {
  Serial.print(F("Slot"));
  if (slt < 10) {Serial.print('0');}
  Serial.print(slt);
  Serial.print(F(": "));
  printBuffer(bufWrite[slt], SLOT_LEN);

  byte retCode = sha204.sha204m_execute(SHA204_WRITE,
                                        SHA204_ZONE_OTP | SHA204_ZONE_COUNT_FLAG, slt,
                                        4, bufWrite[slt],
                                        0, NULL,
                                        0, NULL,
                                        WRITE_COUNT_SHORT, bufTx,
                                        WRITE_RSP_SIZE,    bufRx);
  if (retCode) {Serial.println(F(" write Error"));}
          else {Serial.println(F(" write Ok"));}
}

void loop() {

}

И подробный разбор его работы. Вначале создаём и заполняем двумерный массив bufWrite, состоящий из 64-х байт, организованных в 16 слотов по 4 байта. Это и есть представление OTP зоны нашей микросхемы.

Здесь вы можете установить любые значения байтов массива bufWrite, в соответствии с задачами вашего проекта. Мы взяли просто некоторые тестовые значения этих байтов.

#define SLOT_LEN 4
byte bufWrite[16][4] = {
  {0x00,0x01,0x02,0x03},
  {0x04,0x05,0x06,0x07},
  {0x08,0x09,0x0A,0x0B},
  {0x0C,0x0D,0x0E,0x0F},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
  {0xEE,0xEE,0xEE,0xEE},
};

Далее в цикле последовательно записываются все 16 4-байтовых слотов (блоков) нашего массива в OTP зону микросхемы ATSHA204A.

  for (byte i = 0; i < 16; i++) {
    writeOtp(i);
  }

Саму запись осуществляет функция writeOtp()

void writeOtp(byte slt) {
  Serial.print(F("Slot"));
  if (slt < 10) {Serial.print('0');}
  Serial.print(slt);
  Serial.print(F(": "));
  printBuffer(bufWrite[slt], SLOT_LEN);

  byte retCode = sha204.sha204m_execute(SHA204_WRITE,
                                        SHA204_ZONE_OTP | SHA204_ZONE_COUNT_FLAG, slt,
                                        4, bufWrite[slt],
                                        0, NULL,
                                        0, NULL,
                                        WRITE_COUNT_SHORT, bufTx,
                                        WRITE_RSP_SIZE,    bufRx);
  if (retCode) {Serial.println(F(" write Error"));}
          else {Serial.println(F(" write Ok"));}
}

Вот результат записи 16-и слотов данных в OTP зону микросхемы ATSHA204A:

Тут, опять же, присутствует тонкий момент: значения байтов выводятся только для визуального контроля, а судить об успешности записи мы можем только косвенным образом, по коду возврата функции sha204.sha204m_execute(). Реально прочитать записанные данные и убедиться в их корректности мы сможем только после блокировки Lock Data.

Заключение

В следующей статье мы рассмотрим очень важный этап работы с ATSHA204A — это блокировка Data и OTP зон этой микросхемы (Lock Data). После проведения этой операции снова изменится поведение и функционал ATSHA204A, например, станет доступным чтение её Data и OTP зон памяти.

Ссылки по теме

Работа с SHA-256

ATSHA204 - Обзор

ATSHA204 - Спецификации

ATSHA204 - Библиотека и примеры

ATSHA204A - Чтение зоны конфигурации 1

ATSHA204A - Чтение зоны конфигурации 2

ATSHA204A - Чтение зоны конфигурации 3

ATSHA204A - Запись конфигурации 1

ATSHA204A - Запись конфигурации 2

ATSHA204A - Запись конфигурации 3

ATSHA204A - Запись конфигурации 4

ATSHA204A - Config Lock

ATSHA204A - Работа в режиме Config Lock

ATSHA204A - Работа с зонами памяти

ATSHA204A - Data Lock

ATSHA204A - Чтение Data и OTP зон памяти

ATSHA204A - Команда MAC

ATSHA204A - Аутентификация. Базовый блок

ATSHA204A - Аутентификация. Датчик

ATSHA204A - Криптография и команды

ATSHA204A - Команда CheckMac

ATSHA204A - Команда Nonce

ATSHA204A - Команда GenDig

ATSHA204A - Команда HMAC

ATSHA204A - Команда DeriveKey