Обновить

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

Уровень сложностиПростой
Время на прочтение17 мин
Охват и читатели2.9K
Всего голосов 11: ↑10 и ↓1+13
Комментарии21

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

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

В разделе 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.
https://habr.com/ru/articles/786824/

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

Спасибо!

Ого, CMake. Высший пилотаж!

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

Публикации