Специальная область конфигурации EEPROM
Во всех устройствах Tibbo есть EEPROM (доступ к ней даёт объект stor.). Первые 28 байт EEPROM образуют так называемую «специальную область конфигурации».
В неё входят:
- 8 байт для хранения MAC-адреса устройства
- 20 байт для хранения пароля устройства
По умолчанию специальная область конфигурации недоступна вашему приложению - за это отвечает свойство stor.base. Если его не менять, область хранения данных вашего приложения начинается с адреса 29. Чтобы увидеть данные MAC или пароля, установите stor.base равным 1. Напоминаем: адреса EEPROM отсчитываются с 1.
MAC-адрес
В байтах 1-8 EEPROM хранится MAC-адрес устройства. При включении питания MAC-адрес считывается из EEPROM и записывается в контроллер Ethernet. Текущий MAC всегда можно проверить через свойство только для чтения net.mac объекта net., но напрямую изменить его нельзя. Вместо этого можно изменить данные MAC-адреса в самой EEPROM. При следующей загрузке устройство начнёт использовать новый адрес.
Данные MAC-адреса в EEPROM имеют специальный формат - чтобы TiOS распознала MAC, его нужно соблюдать. Формат такой:
| addr1 | addr2 | addr3 | addr4 | addr5 | addr6 | addr7 | addr8 |
| 6 | MAC0 | MAC1 | MAC2 | MAC3 | MAC4 | MAC5 | Checksum |
В байте по адресу 1 должно быть значение 6 - оно означает, что далее следуют 6 байт данных (MAC-адрес состоит из 6 байт). По адресам со 2 по 7 находится сам MAC-адрес. По адресу 8 хранится контрольная сумма, которая вычисляется так: 255-(modulo8_sum_of_addr_1_through_7).
Вот пример кода, который записывает новый MAC-адрес в EEPROM, а затем перезагружает устройство:
dim s as string
dim x as byte
...
s= "0.2.123.124.220.240" 'supposing, we want to set this MAC
...
...
s=chr(6)+ddval(s) 'added first byte (always 6) and converted readable MAC into bytes
x=255-strsum(s) 'calculated checksum and assigned the result to a BYTE variable ("modulo 8" checksum)
s=s+chr(x) 'now our string is ready
stor.base(1) 'will access the EEPROM from the bottom
x=stor.set(s,1) 'save the data
if x<>len(s) then 'it is a good programming practive to check the result
'failed
else
sys.reboot 'new MAC set, reboot!
end if
...
На задаваемый MAC-адрес есть ограничения. При загрузке MAC в контроллер Ethernet устройство всегда обнуляет первый байт этого адреса. Например, если задать MAC 1.2.3.4.5.6, реально устройство будет использовать MAC 0.2.3.4.5.6.
Если записать неверные данные MAC (неправильный байт «длины» или ошибочную контрольную сумму), устройство проигнорирует сохранённый MAC и загрузится с MAC по умолчанию - 0.1.2.3.4.100.
Пароль
В байтах 9-28 хранится пароль устройства. Пароль хранится в следующем формате:
| addr9 | до 16 байт | 3 байта |
| len | password | MD5 check data |
Байт по адресу 9 указывает длину пароля (не более 16 байт). За ним следует сам пароль, а за ним - 3 контрольных байта. Это первые 3 байта хеша md5, вычисленного по объединённым байтам длины и пароля.
TiOS принимает любой двоичный пароль длиной 0-16 байт (ноль означает «без защиты паролем»). Однако TIDE всегда задаёт 16-байтные пароли. Это MD5-хеши настоящих паролей, которые вы вводите в диалогах Enter Device Password и Change Device Password.
Вот фрагмент кода, который проверяет, действительно ли для устройства задан пароль DEVICE_PASSWORD («Tibbo» в примере ниже). Если данные в EEPROM неверны, код записывает правильные данные и перезагружает устройство. Используя такой код в проекте, вы можете сделать так, чтобы устройства сами себя защищали паролем. Это избавит вас от необходимости вручную задавать пароль каждому устройству через TIDE.
'--------------------------------------------------------------------
Const DEVICE_PASSWORD="Tibbo"
'====================================================================
Sub On_sys_init()
Dim s As String(16)
Dim s2 As String(20)
Dim check As String(3)
Dim x As Byte
'take the hash of password (this is what is supposed to be stored)
s=md5(DEVICE_PASSWORD,"",MD5_FINISH,Len(DEVICE_PASSWORD))
check=md5(chr(16)+s,"",MD5_FINISH,17)
'see if this password is already set
x=stor.base 'will restore the original value later
stor.base=9 'this is where password data recides
s2=stor.getdata(1,20)
If asc(mid(s2,1,1))<>16 Or mid(s2,2,16)<>s Or mid(s2,18,3)<>check Then
'password data in the EEPROM is incorrect! -- set the password again
stor.setdata(chr(16)+s+check,1)
sys.reboot
End If
stor.base=x
...