Как стать автором
Обновить

Настройка ToolChain-а Cборки Прошивок для MIK32 (MIK32 + C+ GCC + GNU Make + OpenOCD)

Уровень сложностиПростой
Время на прочтение16 мин
Количество просмотров1.2K
Всего голосов 10: ↑9 и ↓1+11
Комментарии16

Комментарии 16

Очень полезная статья! Спасибо!

В разделе GDB session надо вставить следующие команды. Они показывают то, где и какая память расположена внутри MIK32

на сколько я помню расположение памяти задается и значит зависит как раз от того что прописано

в скрипте настройки компоновщика.

в ld-файле конфигурации линковщика.

Спасибо за полезную статью!

Вы использовали HAL от вендора? когда я смотрел мне показался сырым.

Немного смутил "Загрузчик (16 Кб)", может сложиться впечатление что там отдельная прошивка. Мне кажется тут не хватает описания режимов загрузки MIK32 и того что в зависимости от Boot0/Boot1 в эту Загрузочную область отображается EEPROM или SPIFI или SRAM.

Вы использовали HAL от вендора?

Да. То самый HAL, что был в архиве с IDE.

Вы использовали HAL от вендора? когда я смотрел мне показался сырым.

Почему именно "сырым"? Чего Вам хотелось бы получить в HAL от вендора?

Немного смутил "Загрузчик (16 Кб)", может сложиться впечатление что там отдельная прошивка.

Монолитный загрузчик не может быть 16kByte. Согласно спеке в MIK32 всего 8kByte EEPROM. Получается, что загрузчик надо утрамбовывать в 8kByte ROM.

На сколькоя понимаю (но это не точно), в области "Загрузчик (16 Кб)" находится BROM с кодом загрузчика, который позволяет проинитить QSPI NOR Flash и запустить код из неё. Активация происходит установкой сигналов BOOT в соответствующее положение.

Да, всё верно, однако это тот самый заводской загрузчик, который поменять нельзя.
Тот, который начинается со смещения 0x00000000. (Загрузочная область (16 КиБ))

Какой-то у Вас очень сложный и тернистый путь. :-) Я просто сделал Makefile и выложил шаблонный проект для MIK32 в репозиторий, снабдив его коротеньким README.md. Выдал студентам и они на его основе сделали свои проекты. Никаких IDE и прочих эклипсов.

PS: Если использовать родной HAL, то EEPROM едва хватает на вывод "Hello, world!". Есть желание переписать HAL в виде небольшого числа заголовочных файлов с inline функциями, #ifdef-ами и возможностью выполнить -flto. Чтоб ничего лишнего за собой не тянул.

Какой-то у Вас очень сложный и тернистый путь.

В программировании нет царских путей.

Сложный и тернистый путь, возможно, гораздо лучше для обучения. Вспомните Гарри Поттера :).

Сказка ложь, да в ней намек.

У Вас ключ -fno-common дважды передается.

Ок, исправил.

Я не до конца понимаю откуда компилятор берет тела функции функции memcpy memset?
Вот прототип находится в файле string.h
C:\xpack-riscv-none-elf-gcc-14.2.0-3\riscv-none-elf\include\string.h

Однако файла string.с просто нет в папке.
C:\xpack-riscv-none-elf-gcc-14.2.0-3

Остается статическая библиотека.

lib/gcc/riscv-none-elf/14.2.0/rv32imc/ilp32/libgcc.a

или
riscv-none-elf/lib/rv32imc/ilp32/libc.a

Вопрос в том какая опция командной строки компилятора подключает libc.a?



Судя по логу компоновщика в сборке участвуют
/lib/rv32imc/ilp32\libc.a
lib/rv32imc/ilp32\libgloss.a
rv32imc/ilp32\libgcc.a

но не ясно кто их явно подключает к сборке.

Я не до конца понимаю откуда компилятор берет тела функции функции memcpy memset?

Это жуткая история, в неё я был вынужден погрузиться недавно по самые уши. В двух словах: современные компиляторы (GCC, LLVM) во-первых распознают код копирования массивов и заменяют его на вызов memcpy/memmove/memset, во-вторых вставляют свой оптимизированный, как им кажется, код вместо библиотечного memcpy/memmove/memset. Внутри современных libc.a нет тела memcpy, так как разработчики библиотек всецело полагаются на компилятор. Иными словами, memcpy это интринсик.

Я столкнулся со следующей проблемой: при компиляции под RV32I, компилятор GCC 14 вставлял очень медленный вариант memcpy состоящий из простейшего цикла побайтового копирования (аналог "rep movsb" на интеллах). Как я только не пытался его отговорить, чтобы он этого не делал - перепробовал с десяток разных флагов, написал свой заоптимизированный вариант memcpy и даже назвал функцию подругому. Но GCC распознал мой хитрый монёвр и заменил мой код на аналог "rep movsb". Единственный способ который сработал это написать функцию memcpy на асме, поместить в отдельный memcpy.S, отдельно ассемблировать её и подключать только на стадии линковки. То есть надо сделать так, чтобы gcc не видел тела этой функции. Иначе он выкинет его и заменит на кусок говнокода.

Я баловался со своей системой когда наткнулся на эту задницу с memcpy. В моей синтезированной СнК нет DMA, покаместь.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации