1 марта 2014 г.

mspgcc і FRAM мікракантролеры MSP430

Калі вы вырашылі напісаць і адладжваць праграму для FRAM мікракантролераў MSP430, у мяне для вас не вельмі прыемная навіна: у mspgcc ёсць баг #349. Яго апісанне ёсць таксама і ў апісанні пакета gcc-msp430 (тое самае што і mspgcc) для Ubuntu:

BEWARE: due to a bug in the memory layout reference of FRAM-based chips, this package DOES NOT WORK with MSP430FR5xxx chips (eg. FraunchPad devkit). DO NOT use gcc-msp430 on that chip series, as you will lose access to JTAG and BSL, and permanently BRICK your chip!

Карацей: калі будзеце карыстацца гэтым кампілятарам ваш чып пераўтварыцца ў цагліну, з-за памылкі пры размеркаванні памяці.

Але надзея не згублена. Ёсць шляхі выкарыстання кампілятара.

Увага! Далей ідзе тэарэтычнае вырашэнне сапраўднай праблемы.

Відавочна, што такія паводзіны мікракантролера выкліканы механізмам абароны зместа ўнутранай памяці. У серыі FRAM мікракантролераў ужываецца электронны засцерагальнік, у адрозненні ад папярэдніх серый, у якіх засцерагальнік быў сапраўдны і разбураўся пры дапамозе адносна высокага напружання.

Механізм абароны памяці


Што вядома пра электронны засцерагальнік? "MSP430FR57xx Family User's Guide" дае адказ:

1.13 JTAG and SBW Lock Mechanism Using the Electronic Fuse
A device can be protected from unauthorized access by restricting accessibility of JTAG commands that can be transferred to the device by the JTAG and SBW interface. This is achieved by programming the electronic fuse. When the device is protected, the JTAG and SBW interface still remains functional, but JTAG commands that give direct access into the device are completely disabled. There are two ways to lock the device. Both of these require the programming of two signatures that reside in FRAM. JTAG Signature 1 (memory location 0FF80h) and JTAG Signature 2 (memory location 0FF82h) control the behavior of the device locking mechanism.


Карацей: байты з 0FF80h па 0FF83h уключна вызначаюць ці будзе працаздольны JTAG.

Таксама гэтыя адрасы выкарыстоўваюцца для табліцы вектараў перапыненняў і з'яўляюцца зарэзерваванымі. Канфлікт тут такі: кампілятар задае апрацоўшчык для усіх перапыненняў, якія не выкарыстаў праграміст. Такім чынам, па адрасам, якія вызначаюць працаздольнасць JTAG, кампілятарам размешчаны нейкія значэнні.

Патчым HEX ці TXT


Як выправіць кампілятар, нажаль, я не ведаю. Але можна прапатчыць канчатковы вобраз памяці праграмы.

Можна выпраўляць вобраз праграмы ў фармаце Intel HEX альбо TI-TXT. Так выглядае частка makefile-а, адказная за пераўтварэнне elf-вобраза ў фармат Intel HEX ды TI-TXT:
$(TARGET_HEX): $(TARGET)
  $(OBJCOPY) -Oihex $< $@
  srec_cat $@ -intel -exclude 0xFF80 0xFF84 -o $@ -intel

$(TARGET_TXT): $(TARGET_HEX)
  srec_cat $< -intel -o $@ -titxt
  srec_cat $@ -titxt -exclude 0xFF80 0xFF84 -o $@ -titxt
  sed 's|$$|\r|g' -i $@
Першы радок (для абодвух правілаў) ― гэта пераўтварэнне ў патрэбны фармат; другі ― выдаленне дадзеных з адрасоў з 0FF80h па 0FF83h уключна; трэці (калі ёсць) ― адзін з шляхоў змяніць фармат канца радкоў з UNIX-фармата на DOS/Windows (тое ж самае робіць праграма unix2dos).

Правіла для пераўтварэння ў фармат TITXT можна трошкі спросціць:
$(TARGET_TXT): $(TARGET_HEX)
  srec_cat $< -intel -exclude 0xFF80 0xFF84 \
  -o - -titxt | sed 's|$$|\r|g' > $@
Вось так выглядае табліца вектароў адразу пасля кампіляцыі (без дадатковых мераў):
@FF80
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 54 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 00 C2
q
А так пасля выпраўлення пры дапамозе srec_cat:
@FF84
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 54 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 00 C2
q

Патчым ELF


Можна выпраўляць elf-вобраз, тады будзе даступна адладка, бо для адладкі карыстаецца elf-файл, а таксама ўсе наступныя вобразы не будуць патрабаваць выпраўлення.

Каб даведацца, па якім адрасе патчыць файл, нам спатрэбіцца праграма msp430-objdump:
$ msp430-objdump -h ./test.elf 

./test.elf:     file format elf32-msp430

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000060  0000c200  0000c200  00000094  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .noinit       00000002  00001c00  0000c260  000000f4  2**1
                  ALLOC
  2 .vectors      00000080  0000ff80  0000ff80  000000f4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  3 .debug_aranges 00000078  00000000  00000000  00000174  2**2
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_info   00000336  00000000  00000000  000001ec  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_abbrev 00000078  00000000  00000000  00000522  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_line   00000219  00000000  00000000  0000059a  2**0
                  CONTENTS, READONLY, DEBUGGING

Цікавіць нас вобласць вектараў (.vectors). У мікракантролеры яны пачынаюцца з адрасу 0FF80h, а вось у elf-файле па адрасу, які можна знайсці ў слупку File off у адпаведным радку. У маім тэставым файле гэта адрас 00F4h.


Упэўніцца ў правільнасці адрасу можна пры дапамозе HEX-рэдактара. Відавочна што "50 C2" (альбо 0C250h) гэта адрас апрацоўшчыка для тых перапыненняў, якія праграміст не выкарыстаў у сваёй праграме.

Калі адрас мы атрымалі, засталося выключна механічныя дзеі, каб замяніць байты на тыя, што нам патрэбны. Зрабіць гэта можна самастойна ў HEX-рэдактары. Але прапаную аўтаматызаваць працэс:
#!/bin/sh

OFFSET=0x`msp430-objdump -h $1 | grep vectors | awk '{print $6}'`
echo -e '\xFF\xFF\xFF\xFF' | \
  dd of=$1 count=4 bs=1 seek=$(($OFFSET)) conv=notrunc status=none
Застаецца захаваць скрыпт і дадаць яго выклік адразу пасля стадыі лінкоўкі.

Вось так будзе выглядаць вобласць вектараў у фармаце TITXT пасля апрацоўкі elf-вобраза:
@FF80
FF FF FF FF 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 54 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2
50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 50 C2 00 C2
q
Форма трошкі адрозніваецца, ад таго што атрымалі вышэй, але змест то жа самы.

1 комментарий:

  1. Максиме,

    Ось тільки зараз я зміг уважно прочитати твоє дослідження. Переїзд на нову квартиру, народження дитини - вилетів з творчого процесу повністю...
    Мені здається. що ти абсолютно правий, хоча й пишеш, що це тільки теоретичні нотатки. Але дуже, дуже схоже на правду!
    При першій же нагоді перевірю твої ідеї практично - і обов'язково доповім тут про результати.
    Залишається лише дивуватися, чому усе це не розповіли нам розробники з Texas Instruments... А ти пробував написати на ТІ Е2Е?
    Радий читати білоруську. Якщо у тебе проблеми з розумінням української мови - скажи, я перейду на москальську без проблем.

    ОтветитьУдалить