Хост-программа boot_PC должна:
- извлекать данные из файлов прошивок форматов IntelHEX и MotorolaS19;
- принимать первоначально по UART байт $14 версии загрузчика boot_uC микроконтроллера;
- при получении байта $14 версии загрузчика boot_uCотправлять в SRAM память микроконтроллера по UART первоначальный блок(модуль, дамп) кода/данных. Формат первоначального блока(модуля, дампа) кода/данных определяется версией начального загрузчика микроконтроллера и для версии $x4 должен быть: первый байт-счетчик показывающий количество последующих байтов (до 255 байт). Байты отправляются в обратном порядке и располагаются в SRAM также в обратном порядке начиная с RAM_END ($03FF). Управление принятому блоку(модулю, дампу) кода/данных будет передано по адресу расположения последнего принятого байта (RAM_END за минусом количества принятых байт);
- отправлять в SRAM память микроконтроллера по UART последующие блоки(модули, дампы) кода/данных, логика и функционал которых определяется только хост-программой boot_PC и не завист от версии начального загрузчика (за исключением процедуры смены модуля, использующей часть кода начального загрузчика;
- каждый блок(модуль, дамп) кода/данных в микроконтроллере должен выполнять возложенный на него текущий функционал (напр. запись/стирание/чтение памяти микроконтроллера, передача ответов/данных хост-программе boot_PC, перенос данных в SRAM из других областей адресного пространства микроконтроллера, передача управления основной (прикладной) программе микроконтроллера при выходе из загрузчика) и уметь принимать по UART и размещать в SRAM очередной блок кода/данных с последующей передачей ему управления;
- желательно умение выполнять функции терминала для общения с основной (прикладной) программой микроконтроллера после выхода из загрузчика;
- желательно умение подгружать внешний дизассемблер для просмотра на лету извлеченного файлов прошивок и/или кода микроконтроллера.
Хост-программа boot_PC может быть написана на любом языке в консоле или окне и обязательно должна соблюдать формат первоначального блока кода/данных в соответствии с версией загрузчика boot_uC. Форматы последующих блоков кода/данных каждый может писать на свой вкус.
Здесь, в силу другого неумения, будем создавать хост-программу boot_PC на C# с использованием ранее написанных классов [FileOpenMemorySorting], [IntelHEXfile], [MotorolaS19file].
В данной статье набросаем консольную программу которая будет уметь:
- открывать файл прошивки в формате IntelHEX или MotorolaS19;
- извлекать содержимое из файла;
- сортировать содержимое по областям SRAM, EEPROM, FLASH;
- выводить отсортированное содержимое в консоль.
// STM8uLoader.cs using System; using System.Collections.Generic; public partial class STM8S103F3 uLoader { public static void Main(string[] arg) { if (arg.Length == 0) {Console.WriteLine("Отсутствуют аргументы командной строки"); Console.ReadKey(); return;} else fileName = arg[0]; Console.WriteLine("Обнаружены {0} аргумент(ов) командной строки", arg.Length); foreach(string strArg in arg){ Console.WriteLine(strArg); }//foreach FileOpenMemorySorting fileSorted = new FileOpenMemorySorting(fileName); Console.Write("\nAll memory:"); foreach( KeyValuePairkvp in fileSorted.GetAllMemoryaddressByteSorted() ){ if(kvp.Key % 16 == 0) Console.Write("\n${0:X4} ", kvp.Key); Console.Write("${0:X2} ", kvp.Value); }// foreach Console.WriteLine("\n"); Console.Write("\nRAM memory:"); foreach( KeyValuePair kvp in fileSorted.GetRAMaddressByteSorted() ){ if(kvp.Key % 16 == 0) Console.Write("\n${0:X4} ", kvp.Key); Console.Write("${0:X2} ", kvp.Value); }// foreach Console.WriteLine("\n"); Console.Write("\nEEPROM memory:"); foreach( KeyValuePair kvp in fileSorted.GetEEPROMaddressByteSorted() ){ if(kvp.Key % 16 == 0) Console.Write("\n${0:X4} ", kvp.Key); Console.Write("${0:X2} ", kvp.Value); }// foreach Console.WriteLine("\n"); Console.Write("\nFLASH memory:"); foreach( KeyValuePair kvp in fileSorted.GetFLASHaddressByteSorted() ){ if(kvp.Key % 16 == 0) Console.Write("\n${0:X4} ", kvp.Key); Console.Write("${0:X2} ", kvp.Value); }// foreach Console.WriteLine("\n"); Console.ReadKey(); } // Main(); static string fileName; } // STM8uLoader.cs
Небольшой файлик на ассемблере с использованием областей RAM, EEPROM, FLASH
stm8/ ; test.asm TITLE "test.asm" MOTOROLA #include "STM8S103F3P.inc" ; ******************************************************** BYTES segment byte at 0000 'RAM_0' dc.b $00, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0A, $0B, $0C, $0D, $0E, $0F ; ******************************************************** WORDS segment byte at 0100 'RAM_1' main_RAM: ldw X, #$03FF ; [AE 03 FF] ldw SP, X ; [94] ; Включаем pull-up на портах (если подтяжка не предусмотрена внешней схемой) ld A, #%11111111 ; [A6 FF] ld PA_CR1, A ; [C7 50 03] ld PB_CR1, A ; [C7 50 08] ld PC_CR1, A ; [C7 50 0D] ld PD_CR1, A ; [C7 50 12] ; настраиваем UART на прием/передачу на скорости 9600, остальные настройки по умолчанию (8 бит, нет бита четности, 1 стоповый бит) ; mov UART1_BRR2, #0 ; [35 00 52 33] для Fmaster=16/8=2МГц и 9600 mov UART1_BRR1, #13 ; [35 0D 52 32] для Fmaster=16/8=2МГц и 9600 mov UART1_CR2, #%00001100 ; [35 0C 52 35] UART1_CR2.TEN <- 1 UART1_CR2.REN <- 1 разрешаем передачу/прием ; включаем светодиод bset PB_DDR,#5 ; bset PB_CR1,#5 ; ; отправляем байт по UART mov UART1_DR, #$15 ; [35 13 52 31] ; уходим во FLASH jp main_FLASH ; ******************************************************** ; WORDS ; segment byte at 4000 'EEPROM' ; немного данных в EEPROM dc.w $1111, $2222, $3333, $4444, $5555, $6666, $7777, $8888 dc.w $9999, $AAAA, $BBBB, $CCCC, $DDDD, $EEEE, $FFFF, $0000 dc.w $0000, $0000, $1111 ; ******************************************************** WORDS ; segment byte at 8080 'FLASH' main_FLASH: ldw X, #$03FF ; [AE 03 FF] ldw SP, X ; [94] ; Включаем pull-up на портах (если подтяжка не предусмотрена внешней схемой) ld A, #%11111111 ; [A6 FF] ld PA_CR1, A ; [C7 50 03] ld PB_CR1, A ; [C7 50 08] ld PC_CR1, A ; [C7 50 0D] ld PD_CR1, A ; [C7 50 12] ; настраиваем UART на прием/передачу на скорости 9600, остальные настройки по умолчанию (8 бит, нет бита четности, 1 стоповый бит) ; mov UART1_BRR2, #0 ; [35 00 52 33] для Fmaster=16/8=2МГц и 9600 mov UART1_BRR1, #13 ; [35 0D 52 32] для Fmaster=16/8=2МГц и 9600 mov UART1_CR2, #%00001100 ; [35 0C 52 35] UART1_CR2.TEN <- 1 UART1_CR2.REN <- 1 разрешаем передачу/прием main_FLASH_cycle: ; включаем светодиод bset PB_DDR,#5 ; bset PB_CR1,#5 ; ; отправляем байт по UART mov UART1_DR, #$13 ; [35 12 52 31] callr main_FLASH_dealay callr main_FLASH_dealay ; выключаем светодиод bres PB_DDR,#5 ; bres PB_CR1,#5 ; ; отправляем байт по UART mov UART1_DR, #$23 ; [35 12 52 31] callr main_FLASH_dealay callr main_FLASH_dealay jra main_FLASH_cycle main_FLASH_dealay: decw X jrne main_FLASH_dealay ret ; [00 00] end ; STM8S103F3P6 ; STM8 - Product class STM8 microcontroller ; S - Family type standart ; 103 - Sub-family type access line ; F - Pin count 20 pins ; 3 - Program memory size 8 Kbytes ; P - Case type TSSOP ; 6 -40...+85 C
И bat-ник для передачи аргумента командной строки:
STM8uLoader test.s19 pause
Программа, прошивка, bat-ник одним архивом[STM8uLoader.zip].
Запускаем bat файл.
Исходники:[boot_PC.zip] и [test.zip] .
Машинные коды STM8 и команды ассемблера здесь. Адресное пространство STM8S103F3 тут.
В следующей статье будем стучаться в COM-порт и плату STM8S103F3.