Прошивка TI TIVA-C с помощью USB DFU
Есть множество способов поместить прошивку в микроконтроллер после того, как она будет готова. Однако, когда речь идет об устройстве, которое в обычном состоянии использует USB порт для связи с компьютером, неплохо бы иметь возможность загружать прошивку именно через него.
У контроллеров TIVA-C TM4C есть возможность воспользоваться режимом USB Device Firmware Update.

Все подробности генерации бинарников и их заливки под катом

Здесь необходимо отметить, что в микроконтроллеры TM4C встроено множество функций библиотеки TivaWare, на чем можно сэкономить в программном коде просто вызывая функции из ROM контроллера. Все эти функции начинаются с соответствующего префикса «ROM_»
В настройках проекта добавим путь до библиотек TivaWare:
"${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/TivaWare_C_Series-2.1.0.12573c"

Теперь, в нужное место (у меня это торчит в обработчике консольной команды команды «ATU») добавляем следующий код:
Его задача, перезапустить USB контроллер в новом режиме, попутно перенастроив все прерывания, чтобы ничего более не мешало.
Запускаем на компиляцию.
Посмотрим, что из себя представляет наш .out файл прошивки:
C:\home\...\Debug>objdump -h usb_dfu_test.out
Мы видим секции, из которых состоит прошивка. Столбец LMA показывает, по какому адресу будут находиться данные, а столбец VMA показывает, по какому адресу программа будет эти данные искать. Как мы видим, секция data находится в области прошивки, но при запуске данные загрузятся в область ОЗУ.
Секция .bss по обеим колонкам находятся по адресу 512Мбайт и выше. Если мы просто сгенерируем bin файл, он получится весом более 0.5Гбйат. И это не баг, это фича
Поэтому генерируем бинарник без соответствующих секций, с помощью ключа -R секция
В Code Composer Studio для этого есть соответствующий пункт в настройках GNU objcopy Utility — воспользуемся им:

Пересобираем проект и наблюдаем в консоли результат:
'Invoking: GNU Objcopy Utility'
«C:/bin/energia/hardware/tools/lm4f/bin/arm-none-eabi-objcopy.exe» -I elf32-littlearm -O binary --remove-section .bss «usb_dfu_test.out» «usb_dfu_test.bin»
'Finished building: usb_dfu_test.bin'
Объем нашего файла составил 4 кбайт.
Здесь мы можем загрузить прошивку каким-нибудь программатором — увы, но первый раз это потребуется.
Запускаем LM Flash Programmer. У меня версия 1613. В качестве интерфейса выбираем USB DFU и видим в списке наше устройство.

не видим? Да, есть такая проблема — в системе наше устройство определяется, но программа его не видит. В этом случае смотрим версии драйверов устройств и пробуем их либо просто переустановить, либо поставить более старые. Я бы однозначно ответил на этот вопрос, да накануне все заработало только со старым драйвером, а сейчас смотрю — определяется под новым. на TI E2E много соответствующих тем, но где косяк — никто не знает :)
Выбираем наш файл прошивки и зашиваем — тыдынь — устройство вновь определяется. Так как мы залили тоже самое — можем вновь попробовать залить что-то более полезное.

Готово!
немного ссылок напоследок:
TI-RTOS USB DFU mode problem — исходный код
TIVA-C TM4C123 ROM User's Guide
LM Flash Programmer
У контроллеров TIVA-C TM4C есть возможность воспользоваться режимом USB Device Firmware Update.

Все подробности генерации бинарников и их заливки под катом
Подготовка проекта:
В Code Composer Studio Создадим пустой проект:
Здесь необходимо отметить, что в микроконтроллеры TM4C встроено множество функций библиотеки TivaWare, на чем можно сэкономить в программном коде просто вызывая функции из ROM контроллера. Все эти функции начинаются с соответствующего префикса «ROM_»
В настройках проекта добавим путь до библиотек TivaWare:
"${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/TivaWare_C_Series-2.1.0.12573c"

Теперь, в нужное место (у меня это торчит в обработчике консольной команды команды «ATU») добавляем следующий код:
Его задача, перезапустить USB контроллер в новом режиме, попутно перенастроив все прерывания, чтобы ничего более не мешало.
Спойлер
#include <stdint.h>
#include <stdbool.h>
//алиасы
#include <inc/hw_memmap.h>
#include <inc/hw_types.h>
#include <inc/hw_ints.h>
#include <inc/hw_nvic.h>
#include <inc/hw_gpio.h>
//драйвера - ROM, выходы и системный клок
#define TARGET_IS_BLIZZARD_RB1
#include <driverlib/rom.h>
#include <driverlib/gpio.h>
#include <driverlib/sysctl.h>
int main(Void)
{ //Отключаем все прерывания, перезапускаем тактирование
ROM_IntMasterDisable();
ROM_SysTickIntDisable();
ROM_SysTickDisable();
uint32_t ui32SysClock;
ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);
ui32SysClock = ROM_SysCtlClockGet();
//активируем аналоговые цепи USB
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
ROM_GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / 100);//ожидаем запуска
//сбрасываем все прерывания
HWREG(NVIC_DIS0) = 0xffffffff;
HWREG(NVIC_DIS1) = 0xffffffff;
HWREG(NVIC_DIS2) = 0xffffffff;
HWREG(NVIC_DIS3) = 0xffffffff;
HWREG(NVIC_DIS4) = 0xffffffff;
int ui32Addr;
for(ui32Addr = NVIC_PRI0; ui32Addr <= NVIC_PRI34; ui32Addr+=4)
{
HWREG(ui32Addr) = 0;
}
HWREG(NVIC_SYS_PRI1) = 0;
HWREG(NVIC_SYS_PRI2) = 0;
HWREG(NVIC_SYS_PRI3) = 0;
//перезапускаем тактирование USB
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_USB0);
ROM_SysCtlUSBPLLEnable();
ROM_SysCtlDelay(ui32SysClock*2 / 3);
//Активируем прерывание и запускаем DFU
ROM_IntMasterEnable();
ROM_UpdateUSB(0);
while(1)
{
}
return 0;
}
Запускаем на компиляцию.
Генерация .bin файла
Теперь начинается самое интересное.Посмотрим, что из себя представляет наш .out файл прошивки:
C:\home\...\Debug>objdump -h usb_dfu_test.out
Спойлер
usb_dfu_test.out: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .isr_vector 0000026c 00000000 00000000 00008000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 0000087c 0000026c 0000026c 0000826c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .rodata 00000008 00000ae8 00000ae8 00008ae8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .eh_frame 00000004 00000af0 00000af0 00008af0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .data 00000434 20000000 00000af4 00010000 2**3
CONTENTS, ALLOC, LOAD, DATA
5 .jcr 00000004 20000434 00000f28 00010434 2**2
CONTENTS, ALLOC, LOAD, DATA
6 .ARM.exidx 00000008 00000f2c 00000f2c 00010f2c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .bss 0000021c 20000438 20000438 00018438 2**2
ALLOC
8 .ARM.attributes 00000035 00000000 00000000 00010f34 2**0
CONTENTS, READONLY
9 .comment 00000070 00000000 00000000 00010f69 2**0
CONTENTS, READONLY
10 .debug_info 0000022a 00000000 00000000 00010fd9 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_abbrev 00000134 00000000 00000000 00011203 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_aranges 00000058 00000000 00000000 00011337 2**0
CONTENTS, READONLY, DEBUGGING
13 .debug_ranges 00000038 00000000 00000000 0001138f 2**0
CONTENTS, READONLY, DEBUGGING
14 .debug_line 0000023a 00000000 00000000 000113c7 2**0
CONTENTS, READONLY, DEBUGGING
15 .debug_str 00000213 00000000 00000000 00011601 2**0
CONTENTS, READONLY, DEBUGGING
16 .debug_frame 0000021c 00000000 00000000 00011814 2**2
CONTENTS, READONLY, DEBUGGING
Мы видим секции, из которых состоит прошивка. Столбец LMA показывает, по какому адресу будут находиться данные, а столбец VMA показывает, по какому адресу программа будет эти данные искать. Как мы видим, секция data находится в области прошивки, но при запуске данные загрузятся в область ОЗУ.
Секция .bss по обеим колонкам находятся по адресу 512Мбайт и выше. Если мы просто сгенерируем bin файл, он получится весом более 0.5Гбйат. И это не баг, это фича
Поэтому генерируем бинарник без соответствующих секций, с помощью ключа -R секция
В Code Composer Studio для этого есть соответствующий пункт в настройках GNU objcopy Utility — воспользуемся им:

Пересобираем проект и наблюдаем в консоли результат:
'Invoking: GNU Objcopy Utility'
«C:/bin/energia/hardware/tools/lm4f/bin/arm-none-eabi-objcopy.exe» -I elf32-littlearm -O binary --remove-section .bss «usb_dfu_test.out» «usb_dfu_test.bin»
'Finished building: usb_dfu_test.bin'
Объем нашего файла составил 4 кбайт.
Здесь мы можем загрузить прошивку каким-нибудь программатором — увы, но первый раз это потребуется.
Настройка системы
Допустим, мы уже запустили прошивку с помощью программатора или отладчика и в системе определилось устройство как на КДПВ.Запускаем LM Flash Programmer. У меня версия 1613. В качестве интерфейса выбираем USB DFU и видим в списке наше устройство.

не видим? Да, есть такая проблема — в системе наше устройство определяется, но программа его не видит. В этом случае смотрим версии драйверов устройств и пробуем их либо просто переустановить, либо поставить более старые. Я бы однозначно ответил на этот вопрос, да накануне все заработало только со старым драйвером, а сейчас смотрю — определяется под новым. на TI E2E много соответствующих тем, но где косяк — никто не знает :)
Выбираем наш файл прошивки и зашиваем — тыдынь — устройство вновь определяется. Так как мы залили тоже самое — можем вновь попробовать залить что-то более полезное.

Готово!
немного ссылок напоследок:
TI-RTOS USB DFU mode problem — исходный код
TIVA-C TM4C123 ROM User's Guide
LM Flash Programmer
2 комментария
austinblackstoneengineering.com/jtag-and-the-stellaris-launchpad/
Возможно ли превратить TM4C в программатор jtag для msp430?
В принципе, ежель написать соответствющую прошивку, то это будет возможно.
например в tiva-c launchpad на один из контроллеров как раз приходится JTAG-отладчик.
Впрочем, проще воспользоваться решением на FTDI.
У меня такой задачи не возникало, ибо имеетс MSP430-JTAG адаптер. Но успешно SWD-шил я как то девайсину, используя msp430g2553 launchpad.