суббота, 30 января 2010 г.

Serial bootloader для TMS320F280x

Некоторое время назад была попытка начать блог. Но кроме выкладывания фотографий рабочего места и написания планов на будущее дело не пошло. Сподвигнутый на писательские подвиги такими героями, как Мегакорпорация (веселые ребята), DI_HALT (выше всяких похвал), решил, что стоит запробовать еще разок. Тем более повод выдался.
Имеется у меня плата, на борту которой супернанотехнологичный (и энергосберегающий!!) МК TMS320F2809 производства мегаконторы Texas Instruments. Возникла надобность грузить его ОЗУ через SCI, все бы хорошо, да вот утилиты, которые есть для этого все дико неудобные: одни монстрообразные до ужаса, другие не позволяют задать скорость COM-порта, через который идет загрузка. Пришлось писать самому - надо же как-то поднимать свой уровень программирования выше быдлокодерства.
Итак, для начала стоит почитать документ от техасцев, чтобы понять, как вогнать процессор в режим загрузки через SCI, какой формат данных, посылаемых при загрузке и т.п. Режим загрузки выбирается тремя пинами: GPIO34, GPIO29, GPIO18. Для загрузки через SCI надо притянуть GPIO34 к земле (лучше через резистор сопротивлением пару кОм), а осталные к питанию (тоже через резисторы, причем в схеме к отладочным платам нарисованы резисторы 100кОм, я мудрить не стал и поставил точно такие). При очередном ресете, процессор окажется в нужном нам режиме и будет ждать данных на проводе. Но перед тем, как начать обмен, необходимо сделать "baud lock": поначалу МК не знает на какой скорости будут передаваться данные, поэтому он должен ее определить. Для этого отправляем ему символ 'a', если все нормально, процессор вышлет в ответ этот же символ.
При этом надо учитывать, что ежели скорость задана выше 100 кбод, то МК не сможет определить бодрейт. Иногда приходится использовать более низкие скорости обмена - это зависит от частоты тактирования процессора. Далее процессор готов к приему данных. Каждый принятый байт отсылается обратно, что может быть полезно для контроля процесса загрузки.
Отдельное слово стоит сказать о формате данных для загрузки и о том, как эти данные получить. Как вы догадались, это все приведено в вышеуказанном документе. Вот кусок оттуда:
AA 08 ;Keyvalue
00 00 00 00 00 00 00 00 ;8 reserved words
00 00 00 00 00 00 00 00
3F 00 00 A0 ;Entrypoint 0x003FA000
02 00 ;Load 2 words - codestart section
00 00 00 00 ;Load block starting at 0x000000
7F 00 9A A0 ;Data block 0x007F, 0xA09A
16 00 ;Load 0x0016 words - ramfuncs section
00 00 02 00 ;Load block starting at 0x000002
22 76 1F 76 2A 00 00 1A 01 00 06 CC F0 ;Data = 0x7522, 0x761F etc...
FF 05 50 06 96 06 CC FF F0 A9 1A 00 05
06 96 04 1A FF 00 05 1A FF 00 1A 76 07
F6 00 77 06 00
55 01 ;Load 0x0155 words - .text section
3F 00 00 A0 ;Load block starting at 0x003FA000
AD 28 00 04 69 FF 1F 56 16 56 1A 56 40 ;Data = 0x28AD, 0x4000 etc...
29 1F 76 00 00 02 29 1B 76 22 76 A9 28
18 00 A8 28 00 00 01 09 1D 61 C0 76 18
00 04 29 0F 6F 00 9B A9 24 01 DF 04 6C
04 29 A8 24 01 DF A6 1E A1 F7 86 24 A7
06 .. ..
.. .. ..
.. .. ..
FC 63 E6 6F
19 00 ;Load 0x0019 words - .cinit section
00 00 18 00 ;Load block starting at 0x000018
FF FF 00 B0 3F 00 00 00 FE FF 02 B0 3F ;Data = 0xFFFF, 0xB000 etc...
00 00 00 00 00 FE FF 04 B0 3F 00 00 00
00 00 FE FF .. .. ..
.. .. ..
3F 00 00 00
02 00 ;Load 0x0002 words - myreset section
00 00 32 00 ;Load block starting at 0x000032
00 00 00 00 ;Data = 0x0000, 0x0000
00 00 ;Block size of 0 - end of data 

Для получения такого файлика из COFF имеется утилита в составе Code Generation Tools - hex2000. Про нее тоже написано в документе.
Изучив данный документ, я за вечер написал утилитку. Пока утилита находится в стадии альфа, но тем не менее работает. Вкратце, как оно работает. Для начала при помощи hex2000 получим hex-файл:
hex2000 -b -boot -sci8 -o filename.hex filename.out
-b - означает, что создается бинарный файл (пока только такие и может использовать утилитка)
-boot - значит готовим данные для загрузки
-sci8 - 8-битный формат данных для загрузки через SCI
-o - задаем имя hex-файла
Затем подаем питание на процессор, жмем ресет и пишем такое:
C2000Boot COM1 19200 filename.hex
В качестве параметров утилитка принимает имя последовательного порта, через который идет загрузка, скорость обмена и путь к hex-файлу. Далее все как описано выше - baud lock и загрузка. Можно производить загрузку и через виртуальный последовательный порт от FTDI. Вскоре выложу проект для VC++ 2005 и сам испоняемый файл.