Настройка ToolChain-нa для Разработки на Микроконтроллерах YTM32x

05085f1ad944e9d6093299d3607f4f72.png

Все микроконтроллеры программируются одинаково, если собирать код из 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

Глядя на оглавление флаера на микросхему в первом приближении складывается такая мозаика.

969beb6c99c8feb85cd1898794f42a3d.png

Каков план?

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

Вот так условно можно представить архитектуру схемотехники YTM32B1M-EVB-0144 Rev.B. CAN 4x, LIN 4x, LED 3x, BTN 2x, ADC 2x, FRAM, EEPROM, USB-UART.

160122c6faa5aeaf9270404f3f9fe580.png

Программатор выглядит так.

beece58d7355d79306f6faa3ba2547af.png

надпись на шильдике гласит

938ba018bee97ecaa46c110085b17562.png

Что надо из документации?

Название документа

колич. страниц

Пояснение

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 очень даже хорошо написан.

61d84f5596d2de386479d2eaefca7075.png

Среди всех сорцов надо обратить особое внимание на некоторые фундаментальные файлы:

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

Подсказка по 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.

Как прошить микроконтроллер?

Тут надо снова вернуться к аппаратному обеспечению. Прежде всего надо соединить оборудование, как показано на схеме.

3734363c606a2f428065d37fb24ec27b.png

Такова расспиновка 10-ти пинового разъёма для программирования P1 по SWD.

0424b5232da95fd907ade8a84ec554ac.png

При подключении программатора J-link в диспетчере устройств должно появиться ещё одно USB устройство: J-Link driver.

4dcf068a99449f2669a52560bcdbb883.png

Формально есть 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.

b445cfa4061422dfa8813024247c91e5.png

Также надо закинуть специальные бинарные файлы

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.

3d89983950f5d3100af671d83711dd05.png

После успешной пере прошивки должен появиться вот такой лог.

Лог успешной перепрошивки

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 пере прошивки.

06ad52d8870fc5fcbf57186206bcc1b9.png

Теперь остается только клюнуть на кнопку Program Device и прошивка будет прописана во Flash память микроконтроллера.

43f974939181202137a3ac265d4641a6.png

Во время загрузки появляется вот такой progress bar

11dece9ef07c15e437ba0d38a78a446e.png

В случае успеха появится вот такой лог

Лог успешной загрузки

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, название микроконтроллера и получаешь прошитый микроконтроллер.

d05be83d2e7ad3eed6ef14f73a47047e.png

Настройка пошаговой отладки.

Надо установить утилиту Ozone. Это отладочный сервер и одновременно отладочный клиент в одном приложении. Причем надо установить именно версии 3.26. После установки программа окажется в папке C:\Program Files\SEGGER\Ozone V3.26 . Как и любой другой отладочный клиент Ozone получает на вход *.elf файл.

При запуске Ozone надо первым делом выбрать целевой микроконтроллер

dcd634446ead334398f3c04791a5d577.JPG

Далее следует явно указать путь к *.elf файлу.

88e56675d523eb994066f54398653fee.JPG

Тут клюём next

557a08ab9c303a554c06603ab52c1be2.JPG

Прошивка загрузится в боевую flash. Ozone весьма удобен в том плане, что он автоматически пере заливает прошивку, если *.elf файл изменился. Достаточно буквально пересобрать код и он тотчас же уже готов к пошаговой отладке.

f0db50ecdbfa138cf11142c30b091eca.jpg

И вот появится пошаговая отладка. Отрабатывает весьма четко. Без глюков.

0d3c2c55de55266e65a9f373b6de40b9.JPG

А это минимальный набор горячих клавиш для работы с отладчиком Ozone

Hot key

Значение

Перевод

F5

Continue

отпустить программу на исполнение

F10

Step Over

перешагнуть через функцию

F11

Step into

зайти во внутрь функции

Shift+F11

Step out

???

Схема ToolChain-a
Суммирую вышесказанное получается вот такой конвейер метаморфоза файлов.

Схема ToolChain-a

Схема ToolChain-a

Отладка

Удалось достучаться до консоли по UART2. Это открывает прямую дорогу для полноценной отладки абсолютно любой остальной подсистемы микроконтроллера: CAN, LIN, PWM и проч.

9cf475acc0fc874b898ff3757923b9e3.png

Можно заметить, что в SDK от YunTo таблица векторов прерываний хранится в RAM памяти по адресу 0×1fff0000. Глядя на *.map файл там как раз переменная __VECTOR_RAM.

445326b4841d5209ac9f5ce82b89a038.png

Также в UART-CLI можно попросить микроконтроллер прогнать модульные тесты

08746e541a2550bc470ad366cd4af850.JPG

Итог

Удалось получить базовое представление о работе с очередным китайским микроконтроллером семейства 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 раза