Настройка ToolChain-нa для Разработки на Микроконтроллерах YTM32x
Все микроконтроллеры программируются одинаково, если собирать код из make скриптов.
Настало время освоить очередное семейство ARM-совместимых микроконтроллеров. За плечами уже AVR, MSP430x, LPC21x, STM32x, MDR32x, ESP32x, SPC58x, CC26×2, NRF53x, AT32Fx. Теперь вот YTM32x от компании YUN TU (Suzhou YTM Semiconductor Co Ltd).
Итак у меня есть экзотический микроконтроллер YTM32B1ME05G0MLQ Судя по маркировке это 32 битный МК с ядром ARM Cortex-M33 c 1MByte Flash памяти.
Код маркировки | переменная | значение |
YTM | Product Status | Qualified |
32 | MCU Type | 32-bit |
B | Product Line | General |
1 | Generation | 1st generation product |
ME | Level | Middle end |
0 | Major Revision | 1st revision |
5 | Memory Size | 1M Byte |
G0 | Reserved | Reserved |
M | Ambient Temperature | -40◦C ~125◦C |
LQ | Package | 144 pin |
Глядя на оглавление флаера на микросхему в первом приближении складывается такая мозаика.
Каков план?
1--Научиться собирать прошивки для микроконтроллера YTM32B1ME05G0MLQ компилятором GCC. Причем собирать сорцы из make файлов.
2--Научиться прошивать *.hex файл с прошивкой во Flash память YTM32B1ME05G0MLQ
3--Научиться отлаживать *.elf прошивку по шагам через интерфейс SWD.
4--Написать первую базовую, полноценную, тестировочную NoRTOS прошивку в которой будет работать драйвер SysTick, Interrupt, GPIO, UART, HardBeat LED, парсер CSV, CLI и модульные тесты, чтобы можно было при помощи CLI и встроенных тестов отлаживать любой другой функционал. То есть довести прошивку до ортодоксально-канонической формы.
В принципе это универсальный план действий для освоения абсолютно любого другого микроконтроллера. Надо просто выполнить эти 4 шага. Остальное уже зависит от специфики конкретного приложения. А эти 4 пункта, как правило всегда присутствуют в любой сборке. Это база.
Аппаратная часть.
Что надо из оборудования?
№ | Название | Пояснение |
1 | Учебно-тренировочная электронная плата YTM32B1M-EVB-0144 Rev.B | Учебно-тренировочная электронная плата с микроконтроллером YTM32B1ME05G0MLQ 2245H на борту |
2 | Кабель переходник с USB-A на USB Type-C | Для соединения отладочной платы и PC |
3 | Программатор отладчик J-link V9 (или V12) USB-JTAG для ARM | Программатор для загрузки прошивки. Нужен именно V9. Так как поддержка ARM Cortex-M33 начинается именно с V9. Для загрузки прошивки в микроконтроллер |
4 | шлейф 20 pin | Для соединения MCU и программатора |
5 | шлейф 10 pin | Для соединения MCU и программатора |
6 | Переходник с шлейфа 20 пин в шлейф 10 пин | Для соединения MCU и программатора |
7 (opt) | Перемычки вилка-гнездо. | Для соединения программатора с платой. |
Вы узнаете электронную плату YTM32B1M-EVB-0144 Rev.B вот по этой фотографии
YTM32B1M-EVB-0144 Rev.B
Вот так условно можно представить архитектуру схемотехники YTM32B1M-EVB-0144 Rev.B. CAN 4x, LIN 4x, LED 3x, BTN 2x, ADC 2x, FRAM, EEPROM, USB-UART.
Программатор выглядит так.
надпись на шильдике гласит
Что надо из документации?
№ | Название документа | колич. страниц | Пояснение |
1 | YTM32B1ME0x Data Sheet | 45 | Флаер на продукт |
2 | YTM32B1ME0x Reference Manual | 720 | Спецификация на микроконтроллер. Разметка памяти. Список прерываний. |
5 | GNU Make | 224 | Спека на GNU make |
6 | The GNU linker | 122 | Спека на компоновщик |
4 | Using the GNU Compiler Collection | 1006 | Спека на компилятор GCC |
3 | ARMv8-M Architecture Reference Manual | 1364 | Спецификация ядра |
Что надо из ПО?
№ | Программа | Версия | Пояснение |
1 | Tera Term | 4.106 | Терминал последовательного порта для полнодуплексного доступа к UART-CLI. |
2 | arm-none-eabi-gcc.exe (GNU Arm Embedded Toolchain 10.3–2021.10) 10.3.1 20210824 (release) | 10.3.1 | GCC компилятор языка программирования Си |
3 | GNU Make | 4.4.1 | Система сборки |
8 | JRE | ? | Виртуальная машина Java для запуска Eclipse. Можно скачать на сайте Oracle. |
4 | Eclipse IDE for C/C++ Developers | 4.23.0 | Текстовый редактор для написания кода |
6 | Segger JFlash.exe версии 6.20 | 6.20 | Утилита для загрузи и считывания файла с прошивкой |
5 | Ozone — The J-Link Debugger C:\Program Files\SEGGER\Ozone | 3.26 | Отладочный сервер с отладочным клиентом для встраиваемых систем. |
7 | JRun.exe | Утилита для обновления прошивки по *.elf файлу |
Колонка версия тут указана не случайно. Особенно для JFlash и Ozone. С другими версиями я не гарантирую, что инструкция будет совпадать с реальностью. Все программы добавляем в переменную PATH, чтобы можно было их вызывать просто по имени.
На самом деле, если вы до этого уже программировали другой микроконтроллер с ARM ядром компилятором GCC, то установка Eclipse, компилятора GCC и системы сборки Make абсолютно ничем не отличается от того, как это делалось в случае м для ARM-Coertex M4. Про это можно почитать тут:
В случае с YTM32x надо лишь акцентировать внимание на некоторых моментах.
Программная часть
Каждый нормальный вендор чипов бесплатно дает HAL для своего чипа. YunTu не исключение. Надо зарегистрироваться на их сайте, придумать логин и пароль. После чего можно скачать спецификации на микроконтроллер, схемотехнику учебно-тренировочной электронной платы и тонны исходного кода HAL в SDK. Там же в личном кабинете можно получить наводку на сайты с GCC, Jlink, Ozone и прочее.
Исходники HAL можно взять с официального сайта. называется это SDK. Надо только зарегистрироваться и получишь много бесплатного Си-кода. Причем сам код HAL очень даже хорошо написан.
Среди всех сорцов надо обратить особое внимание на некоторые фундаментальные файлы:
YTM32B1ME0_startup_gcc.S — это код процедуры Reset_Handler, который отрабатывает до вызова функции main (). Он написан на ассемблере. Тут происходит отключение прерываний, обнуление регистров процессора, инициализация глобальных переменных, инициализация регистра указывающего на начало стековой RAM памяти, вызов функции SystemInit и вызов функции main (). Тут же можно посмотреть как называются функции обработчики прерываний, например SysTick_Handler.
YTM32B1ME0_1_3_1/YTM32Bx_SDK/platform/devices/YTM32B1ME0/linker/gcc/flash.ld — это конфигурация для компоновщика. Тут указывается сколько у микроконтроллера RAM и ROM памяти, сколько стековой памяти, сколько памяти в куче. Указывается начало RAM памяти, начало ROM памяти. Указывается название массива isr_vector, который отвечает за таблицу векторов прерываний. Тут указано из каких секций состоит программа и в какой последовательности эти секции следуют. LD скрипт — это целый язык программирования со своими переменными, операторами, функциями и комментариями. Небольшой ликбез по LD можно посмотреть тут.
Подсказка по RAM и ROM памяти для MCU YTM32B1ME05G0MLQ
YTM32B1ME0_1_3_1\YTM32Bx_SDK\platform\devices\YTM32B1ME0\startup\system_YTM32B1ME0.c — в сорце system_YTM32B1ME0.c определена функция SystemInit(). Эта функция вызывается до функции main (). SystemInit включается сопроцессор для вычислений в плавающей точке, отключает сторожевой таймер, включает модуль защиты памяти MPU и прочее. Тут же лежит функция для программной перезагрузки микроконтроллера SystemSoftwareReset.
Особенность YTM32Bx_SDK в том, что разработчики на стороне YunTu решили, что таблица векторов прерываний будет по умолчанию хранится в RAM памяти. Поэтому такие драйверы, как UART при инициализации пополняют таблицу векторов прерываний прямо во время исполнения прошивки функцией INT_SYS_InstallHandler.
Далее исходный код добавляется по мере потребности учитывая специфику проекта. На GitHab тоже находятся множество образцовых проектов прошивок для микроконтроллера YTM32B1ME0x.
Система сборки.
В качестве системы сборки я по-прежнему пере использую make скрипты.
Корневой make файл с правилами сборки проекта
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
$(info mkfile_path:$(mkfile_path) )
MK_PATH := $(subst /cygdrive/c/,C:/, $(MK_PATH))
$(info MK_PATH=$(MK_PATH))
BUILD_DIR=build
EXTRA_TARGETS=
INCDIR := $(subst /cygdrive/c/,C:/, $(INCDIR))
SOURCES_TOTAL_C += $(SOURCES_C)
SOURCES_TOTAL_C += $(SOURCES_CONFIGURATION_C)
SOURCES_TOTAL_C += $(SOURCES_THIRD_PARTY_C)
SOURCES_TOTAL_C := $(subst /cygdrive/c/,C:/, $(SOURCES_TOTAL_C))
SOURCES_ASM := $(subst /cygdrive/c/,C:/, $(SOURCES_ASM))
LIBS := $(subst /cygdrive/c/,C:/, $(LIBS))
LDSCRIPT := $(subst /cygdrive/c/,C:/, $(LDSCRIPT))
#@echo $(error SOURCES_ASM=$(SOURCES_ASM))
include $(WORKSPACE_LOC)make_scripts/toolchain.mk
WORKSPACE_LOC := $(subst /cygdrive/c/,C:/, $(WORKSPACE_LOC))
FLOAT-ABI = -mfloat-abi=soft
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
CSTANDARD = -std=c99
AS_DEFS =
# AS includes
AS_INCLUDES =
ifeq ($(DEBUG), Y)
CFLAGS += -g3 -ggdb -gdwarf-2
COMPILE_OPT += -O0
else
COMPILE_OPT += -Os
endif
COMPILE_OPT += -fmessage-length=0
COMPILE_OPT += -fsigned-char
COMPILE_OPT += -fno-common
COMPILE_OPT += -fstack-usage
COMPILE_OPT += -fzero-initialized-in-bss
COMPILE_OPT += -finline-small-functions
COMPILE_OPT += -Werror=missing-prototypes
COMPILE_OPT += -Werror=address
COMPILE_OPT += -Werror=switch
COMPILE_OPT += -Werror=array-bounds=1
COMPILE_OPT += -Werror=comment
COMPILE_OPT += -Werror=div-by-zero
COMPILE_OPT += -Werror=duplicated-cond
COMPILE_OPT += -Werror=shift-negative-value
COMPILE_OPT += -Werror=duplicate-decl-specifier
COMPILE_OPT += -Werror=enum-compare
COMPILE_OPT += -Werror=uninitialized
COMPILE_OPT += -Werror=empty-body
COMPILE_OPT += -Werror=unused-but-set-parameter
COMPILE_OPT += -Werror=unused-but-set-variable
COMPILE_OPT += -Werror=float-equal
COMPILE_OPT += -Werror=logical-op
COMPILE_OPT += -Werror=implicit-int
COMPILE_OPT += -Werror=implicit-function-declaration
COMPILE_OPT += -Werror=incompatible-pointer-types
COMPILE_OPT += -Werror=int-conversion
COMPILE_OPT += -Werror=old-style-declaration
COMPILE_OPT += -Werror=maybe-uninitialized
COMPILE_OPT += -Werror=redundant-decls
COMPILE_OPT += -Werror=sizeof-pointer-div
COMPILE_OPT += -Werror=misleading-indentation
COMPILE_OPT += -Werror=missing-declarations
COMPILE_OPT += -Werror=missing-parameter-type
COMPILE_OPT += -Werror=overflow
COMPILE_OPT += -Werror=parentheses
COMPILE_OPT += -Werror=pointer-sign
COMPILE_OPT += -Werror=return-type
COMPILE_OPT += -Werror=shift-count-overflow
COMPILE_OPT += -Werror=strict-prototypes
COMPILE_OPT += -Werror=unused-but-set-variable
COMPILE_OPT += -Werror=unused-function
COMPILE_OPT += -Werror=unused-variable
COMPILE_OPT += -Werror=missing-field-initializers
COMPILE_OPT += -Wno-stringop-truncation
COMPILE_OPT += -Wno-format-truncation
COMPILE_OPT += -Wno-restrict
COMPILE_OPT += -Wno-format
COMPILE_OPT += -Wno-cpp #TODO temp
COMPILE_OPT += -Wno-discarded-qualifiers
COMPILE_OPT += -Wmissing-prototypes
#Perform dead code elimination
COMPILE_OPT += -fdce
#Perform dead store elimination
COMPILE_OPT += -fdse
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) $(COMPILE_OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS += $(CSTANDARD)
CFLAGS += -Wall
CFLAGS += $(MCU) $(OPT) $(COMPILE_OPT) -fdata-sections -ffunction-sections $(INCDIR)
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
CPP_FLAGS += $(CSTANDARD) $(INCDIR) $(OPT) $(COMPILE_OPT)
LINKER_FLAGS += -Xlinker --gc-sections
LINKER_FLAGS += -lrdimon --specs=rdimon.specs
LINKER_FLAGS += -u _scanf_float
LINKER_FLAGS += -u _printf_float
ifeq ($(LIBC), Y)
LIBS += -lc
endif
ifeq ($(MATH_LIB), Y)
LIBS += -lm
endif
LIBDIR =
LDFLAGS += $(MCU)
LDFLAGS += -T$(LDSCRIPT)
LDFLAGS += $(LIBDIR)
LDFLAGS += $(LIBS)
LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
LDFLAGS += $(LINKER_FLAGS)
ARTIFACTS += $(BUILD_DIR)/$(TARGET).bin
ARTIFACTS += $(BUILD_DIR)/$(TARGET).hex
ARTIFACTS += $(BUILD_DIR)/$(TARGET).elf
.PHONY: all
# default action: build all
all: $(EXTRA_TARGETS) $(ARTIFACTS)
.PHONY: generate_definitions
generate_definitions:
$(info GenerateDefinitions...)
$(PREPROCESSOR_TOOL) $(CPP_FLAGS) $(WORKSPACE_LOC)empty_source.c -dM -E> c_defines_generated.h
$(SORTER_TOOL) -u c_defines_generated.h -o c_defines_generated.h
# build the application
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(SOURCES_TOTAL_C:.c=.o)))
vpath %.c $(sort $(dir $(SOURCES_TOTAL_C)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(SOURCES_ASM:.S=.o)))
vpath %.S $(sort $(dir $(SOURCES_ASM)))
TOTAL_FILES := $(words $(OBJECTS))
$(info TOTAL_FILES:$(TOTAL_FILES) )
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(eval CURRENT_CNT=$(shell echo $$(($(CURRENT_CNT)+1))))
@echo Compiling $(CURRENT_CNT)/$(TOTAL_FILES) $@
@$(CC) -c -MD $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
$(SZ) $@
$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(HEX) $< $@
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(BIN) $< $@
$(BUILD_DIR):
mkdir -p $@
# clean up
.PHONY: clean
clean:
-rm -fR $(BUILD_DIR)
# dependencies
-include $(wildcard $(BUILD_DIR)/*.d)
# *** EOF ***
Особенности компоновки. Какую выбрать libc?
При программировании на Си нужны стандартные функции, такие как printf () sprintf () и прочее. Они обычно распространяются в виде предварительно скомпилированных бинарных *.a файлов и лежат в папке с компилятором. В моём случае это папка
C:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2021.10
Называется эта библиотека libc. Их очень много реализаций: glibc, picolibc, nanolib, Newlib и прочее. От выбора той или иной libc зависит размер получившегося бинаря.
Собирая код внутри статической библиотеки libc.a у вас может возникнуть ошибка компоновщика про отсутствие определения тел функций для системных вызовов. Системные вызовы — это функции _sbrk, _write, _close, _fstat, _isatty, _lseek, _read, abort, _exit, _kill и _getpid. Именно эти функции вызываются внутри libc.
Вам надо решить какую Вы выберете реализацию libc. libc — это статическая библиотека с реализацией таких функций как printf (), scanf (), snprintf () и прочее.
Реализация libc | ключ компоновoику | Комментарий |
nosys | -specs=nosys.specs | Вставляет пустые функции для системных вызовов |
newlib-nano | -specs=nano.specs | Частичная реализация libc |
rdimon | --specs=rdimon.specs | -lrdimon |
Newlib | no data | Частичная реализация libc |
picolibc | no data | Частичная реализация libc |
nolibc | -nolibc | no data |
Я пока выбрал rdimon.
Как прошить микроконтроллер?
Тут надо снова вернуться к аппаратному обеспечению. Прежде всего надо соединить оборудование, как показано на схеме.
Такова расспиновка 10-ти пинового разъёма для программирования P1 по SWD.
При подключении программатора J-link в диспетчере устройств должно появиться ещё одно USB устройство: J-Link driver.
Формально есть 4 способа прошить микроконтроллер семейства YTM32х. Вот они перед вами.
# | Утилита | Артефакт на входе | Примечание |
1 | JFlash.exe* | *.hex | Можно прошить *.bat скриптом, если есть лицензия на отладчик j-link |
2 | JFlashLight.exe | *.hex | Возможна только ручная пере прошивка курсором мышки в GUI клиенте |
3 | JRun.exe* | *.elf | Появилась только в последних версиях |
4 | Ozone.exe | *.elf | Прошивка перед пошаговой отладкой |
Патч к J-link
Чтобы Jlink понял как прошивать новое семейство микроконтроллеров надо попатчить программу SEGGER JLink V6.20. По сути патч сводится вот к такому добавлению в файл JLinkDevices.xml.
Также надо закинуть специальные бинарные файлы
Devices/YTMicro/YTM32B1ME0/YTM32B1ME0_Main.FLM
и
Devices/YTMicro/YTM32B1ME0/YTM32B1ME0_Dflash.FLM
Прошивка микроконтроллера утилитой JFlash.exe
Откуда берутся файлы с расширением *.FLM я пока сказать не могу. Будем считать, что файлы появились при помощи волшебной палочки.
Чтобы загрузить прошивку нужна утилита JFlash.exe. Эта утилита на вход получает два файла: *.hex файл с прошивкой и *.jflash файл с конфигурацией YTM32B1M4H0VLQT_SWD.jflash, который хранит такие метаданные как интерфейс, битовая скорость интерфейса, название микроконтроллера, начало памяти
YTM32B1M4H0VLQT_SWD.jflash
AppVersion = 62000
FileVersion = 2
[GENERAL]
ConnectMode = 0
CurrentFile = ""
DataFileSAddr = 0x00000000
GUIMode = 0
HostName = ""
TargetIF = 1
USBPort = 0
USBSerialNo = 0x00000000
[JTAG]
IRLen = 0
MultipleTargets = 0
NumDevices = 0
Speed0 = 4000
Speed1 = 4000
TAP_Number = 0
UseAdaptive0 = 0
UseAdaptive1 = 0
UseMaxSpeed0 = 0
UseMaxSpeed1 = 0
[CPU]
NumInitSteps = 1
InitStep0_Action = "Reset"
InitStep0_Value0 = 0x00000000
InitStep0_Value1 = 0x00000000
InitStep0_Comment = "Reset and halt target"
NumExitSteps = 0
UseScriptFile = 0
ScriptFile = ""
UseRAM = 1
RAMAddr = 0x20000000
RAMSize = 0x00010000
CheckCoreID = 0
CoreID = 0x00000000
CoreIDMask = 0x0F000FFF
UseAutoSpeed = 0x00000001
ClockSpeed = 0x00000000
EndianMode = 0
ChipName = "YTMicro YTM32B1ME05G0MLQT"
[FLASH]
NumBanks = 2
[FLASH0]
aRangeSel[1] = 0-511
BankName = "Internal Flash"
BankSelMode = 1
BaseAddr = 0x00000000
[FLASH1]
aRangeSel[1] = 0-255
BankName = "Internal Flash"
BankSelMode = 1
BaseAddr = 0x00100000
[PRODUCTION]
AutoPerformsErase = 1
AutoPerformsProgram = 1
AutoPerformsSecure = 0
AutoPerformsStartApp = 0
AutoPerformsUnsecure = 0
AutoPerformsVerify = 1
EnableTargetPower = 0
EraseType = 2
MonitorVTref = 0
MonitorVTrefMax = 0x0000157C
MonitorVTrefMin = 0x000003E8
OverrideTimeouts = 0
ProgramSN = 0
SerialFile = ""
SNAddr = 0x00000000
SNInc = 0x00000001
SNLen = 0x00000004
SNListFile = ""
SNValue = 0x00000001
StartAppType = 0
TargetPowerDelay = 0x00000014
TimeoutErase = 0x00003A98
TimeoutProgram = 0x00002710
TimeoutVerify = 0x00002710
VerifyType = 1
Вот так выглядит скрипт flash_Jlink.bat пере прошивки.
cls
set project_name=ytm32b1m_evb_0144_rev_b_mbr_gcc_m
set flash_tool=JFlash.exe
set mcu_config=YTM32B1M4H0VLQT_SWD_620.jflash
::set mcu_config=YTM32B1ME0_Main.FLM
set artefact_hex=build\%project_name%.hex
set option=
set option=%option% -openprj%mcu_config%
set option=%option% -open%artefact_hex%
set option=%option% -programverify
set option=%option% -startapp
set option=%option% -exit
%flash_tool% %option%
Надо прописать в переменную окружения PATH адрес к утилите JFlash.exe. В моём случае это C:\Program Files (x86)\SEGGER\JLink_V620\JFlash.exe
После успешной пере прошивки должен появиться вот такой расклад GUI.
После успешной пере прошивки должен появиться вот такой лог.
Лог успешной перепрошивки
Application log started
- J-Flash V6.20 (J-Flash compiled Sep 8 2017 18:04:56)
- JLinkARM.dll V6.20 (DLL compiled Sep 8 2017 18:04:35)
Opening project file [YTM32B1M4H0VLQT_SWD_620.jflash] ...
- Project opened successfully
Opening data file [build\ytm32b1m_evb_0144_rev_b_mbr_gcc_m.hex] ...
- Data file opened successfully (39612 bytes, 1 range, CRC of data = 0x55979B5C, CRC of file = 0x5B2D5825)
Checking if selected data fits into selected flash sectors.
Programming and verifying target (39612 bytes, 1 range) ...
- Connecting ...
- Connected successfully
- Start of determining flash info (Bank 0 @ 0x00000000)
- End of determining flash info
- Flash bank info:
- 512 * 2 KB @ 0x00000000
- Start of preparing flash programming
- End of preparing flash programming
- Start of determining dirty areas in flash cache
- End of determining dirty areas
- CPU speed could not be measured.
- Start of erasing sectors
- Erasing range 0x00000000 - 0x00003FFF (008 Sectors, 16 KB)
- Erasing range 0x00004000 - 0x00007FFF (008 Sectors, 16 KB)
- Erasing range 0x00008000 - 0x00009FFF (004 Sectors, 8 KB)
- End of erasing sectors
- Start of flash programming
- Programming range 0x00000000 - 0x00007FFF (016 Sectors, 32 KB)
- Programming range 0x00008000 - 0x00009FFF (004 Sectors, 8 KB)
- End of flash programming
- Flash programming performed for 1 range (40960 bytes)
- 0x0000 - 0x9FFF (020 Sectors, 40 KB)
- Start of verifying flash
- End of verifying flash
- Start of restoring
- End of restoring
- Target programmed and verified successfully (CRC = 0xE4E7952A) - Completed after 3.712 sec
Starting application ...
- Disconnecting ...
- Disconnected
- Connecting via USB to J-Link device 0
- Target application started
Обновление утилитой JFlashLight.exe
Прошивку можно загрузить при помощи утилиты JFlashLite.exe. Это клиентская утилита с GUI интерфейсом, чтобы прошивать микроконтроллеры программаторами j-link. При первом запуске следует выбрать название микроконтроллера YTM32B1ME05G0MLQ, интерфейс пере прошивки SWD и битовую скорость 1000 kbit/s пере прошивки.
Теперь остается только клюнуть на кнопку Program Device и прошивка будет прописана во Flash память микроконтроллера.
Во время загрузки появляется вот такой progress bar
В случае успеха появится вот такой лог
Лог успешной загрузки
Downloading C:\projects\workspace\board_name\source\projects\ytm32b1m_evb_0144_rev_b_mbr_gcc_m\build\ytm32b1m_evb_0144_rev_b_mbr_gcc_m.hex to YTM32B1ME05G0MLQT via SWD-Interface@1000kHz
Programming Thread started.
Device "YTM32B1ME05G0MLQT" selected.
Found SW-DP with ID 0x6BA02477
Scanning AP map to find all available APs
AP[2]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x84770001)
AP[1]: APB-AP (IDR: 0x54770002)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410FD214. Implementer code: 0x41 (ARM)
Found Cortex-M33 r0p4, Little endian.
FPUnit: 8 code (BP) slots and 0 literal slots
Security extension: not implemented
CoreSight components:
ROMTbl[0] @ E00FF000
ROMTbl[0][0]: E000E000, CID: B105900D, PID: 000BBD21 SCS
ROMTbl[0][1]: E0001000, CID: B105900D, PID: 000BBD21 DWT
ROMTbl[0][2]: E0002000, CID: B105900D, PID: 000BBD21 FPB
ROMTbl[0][3]: E0000000, CID: B105900D, PID: 000BBD21 ???
ROMTbl[0][5]: E0041000, CID: B105900D, PID: 002BBD21 ETM
ROMTbl[0][6]: E0042000, CID: B105900D, PID: 000BBD21 ETB
Debugger initialized successfully.
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (43008 bytes)
J-Link: Flash download: Total time needed: 3.411s (Prepare: 0.020s, Compare: 1.065s, Erase: 0.551s, Program: 1.217s, Verify: 0.545s, Restore: 0.009s)
Programming Thread exited
Programming done
Обновление прошивки утилитой JRun.exe
В поздних версиях J-link ПО ещё можно прошиваться утилитой JRun.exe. Даешь elf, название микроконтроллера и получаешь прошитый микроконтроллер.
Настройка пошаговой отладки.
Надо установить утилиту Ozone. Это отладочный сервер и одновременно отладочный клиент в одном приложении. Причем надо установить именно версии 3.26. После установки программа окажется в папке C:\Program Files\SEGGER\Ozone V3.26 . Как и любой другой отладочный клиент Ozone получает на вход *.elf файл.
При запуске Ozone надо первым делом выбрать целевой микроконтроллер
Далее следует явно указать путь к *.elf файлу.
Тут клюём next
Прошивка загрузится в боевую flash. Ozone весьма удобен в том плане, что он автоматически пере заливает прошивку, если *.elf файл изменился. Достаточно буквально пересобрать код и он тотчас же уже готов к пошаговой отладке.
И вот появится пошаговая отладка. Отрабатывает весьма четко. Без глюков.
А это минимальный набор горячих клавиш для работы с отладчиком Ozone
Hot key | Значение | Перевод |
F5 | Continue | отпустить программу на исполнение |
F10 | Step Over | перешагнуть через функцию |
F11 | Step into | зайти во внутрь функции |
Shift+F11 | Step out | ??? |
Схема ToolChain-a
Суммирую вышесказанное получается вот такой конвейер метаморфоза файлов.
Схема ToolChain-a
Отладка
Удалось достучаться до консоли по UART2. Это открывает прямую дорогу для полноценной отладки абсолютно любой остальной подсистемы микроконтроллера: CAN, LIN, PWM и проч.
Можно заметить, что в SDK от YunTo таблица векторов прерываний хранится в RAM памяти по адресу 0×1fff0000. Глядя на *.map файл там как раз переменная __VECTOR_RAM.
Также в UART-CLI можно попросить микроконтроллер прогнать модульные тесты
Итог
Удалось получить базовое представление о работе с очередным китайским микроконтроллером семейства YTM32. Теперь понятно, как собирать код, прошивать бинарь, как выполнять пошаговую отладку прошивке на target устройстве и как запустить UART-CLI. Всё это открывает прямую дорогу к полноценной разработке на китайских микроконтроллерах YTM32x от Yun Tu.
Этот текст в очередной раз подтверждает тот факто, что все микроконтроллеры программируются одинаково, если собирать код из make файлов. Это и есть основное достоинство системы сборки GNU Make.
Надеюсь, что этот текст поможет и другим программистам МК наладить Toolchain для сборки программ для микроконтроллеров YTM32x.
Словарь
Акроним | Расшифровка |
GCC | GNU Compiler Collection |
YTM32 | YUN TU |
SWD | Serial Wire Debug |
Ссылки
Habrahabr.ru прочитано 3354 раза