Как сделать arm процессор
У меня есть несколько вопросов о том, как я буду проектировать свой собственный процессор на базе ARM?
- Как начать с лицензии ARM и получить пакет, готовый для пайки на плату?
- Что я получу от ARM (я уверен, что у них есть несколько вариантов лицензий для раздачи - лицензия на архитектуру (стиль Qualcomm Snapdragon) и лицензия на ядро (стиль TI OMAP))?
- Какие инструменты мне нужны, чтобы получить «что-то» от ARM?
- Что я отправляю на завод?
- Я считаю, что только некоторые литейные компании имеют лицензию на травление ядра ARM на кремниевой пластине. Я прав?
- Будучи студентом, могу ли я позволить себе делать это на FPGA? Как мне получить опыт для чего-то подобного?
Проблема в том, что ваш вопрос относится к рабочему процессу, которому вы не сможете следовать. Рабочие процессы, которым вы можете следовать - используя оригинальный или свободно доступный дизайн в HDL для нацеливания на ПЛИС, - так же отличаются от тех, что предполагаются на самом деле.
Ядро Cortex-M1 , кажется, предназначено для работы в любом соответствующим образом способной FPGA. Основные поставщики ПЛИС имеют IP-лицензию и предоставляют ее разработчику, как и любое другое программное ядро. Я предполагаю, что не бесплатно, но есть программы, доступные специально для академического использования.
Вот как компании это делают:
- Привлечь около 10 миллионов долларов США.
- Вести переговоры с ARM, чтобы получить лицензию. Это, вероятно, будет стоить как минимум 1 миллион долларов США.
- Получить файлы дизайна от ARM. Скорее всего, это будет VHDL, Verilog или «зашифрованный» список соединений.
- Создайте свой собственный чип, используя смесь вашей собственной логики (для периферийных устройств) и того, что дала вам ARM. Этот шаг, вероятно, потребует дорогостоящего программного обеспечения САПР и небольшой команды экспертов. Ожидайте потратить не менее 5 миллионов долларов США и несколько лет.
- Получите маски, сделанные для самого чипа. Если вы используете какой-либо современный полупроводниковый процесс, то это обойдется примерно в 1 миллион долларов США.
- Получи сам чип сделанный. Цена варьируется, но должна быть менее 0,5 млн. Долларов США.
- Отладьте чип, который вы создали, исправьте ошибки, затем вернитесь к шагу 5, пока у вас не появится что-то, что вы сможете продать.
Вот как ВЫ это делаете:
- Пройдите курс по компьютерной архитектуре на уровне магистратуры в вашем местном университете.
- Пройдите больше курсов по цифровой логике и прочему.
- Разработка процессора с нуля в VHDL или Verilog.
- Дизайн другого процессора с нуля.
- Посмотрите на набор инструкций ARM и спроектируйте совместимый процессор.
- Сделайте так, чтобы ваш ARM-совместимый процессор работал в FPGA.
- Не распространяйте свой исходный код VHDL / Verilog, если вы не хотите, чтобы вас судили.
- Используйте свой опыт ARM, чтобы написать хорошую диссертацию для вашего доктора философии.
- Используйте свою докторскую степень, чтобы получить работу в ARM или TI, или кто-либо еще. Затем повторите процесс, используя предыдущие 7 шагов о том, как компания это делает.
Итак, этот список немного насмешливый, но он в основном правильный. Дело в том, что даже не связывайтесь с ARM напрямую, потому что, скорее всего, у вас нет денег. И не делайте ничего, что возбудит против вас иск ARM.
Любой хороший курс будет включать в себя базовую структуру различных типов процессоров и то, как они все работают. Темы должны охватывать микрокод, декодирование команд, ALU, доступ к памяти, кэш, регистры, конвейерную обработку, опасности данных, предварительную выборку инструкций и т. Д.
Есть ли какая-либо причина, по которой набор инструкций ARM сам по себе был бы более патентоспособным, чем любой из других процессоров, клонов которых предостаточно? Конечно, есть некоторые архитектурные особенности, которые запатентованы, но если цель состоит в том, чтобы спроектировать процессор, который будет работать с существующими компиляторами, создаст ли сам набор инструкций проблему?
@supercat Обычно инструкции сами по себе не являются патентоспособными, если они не включают некоторые архитектурные элементы. MIPS сделали это со своими процессорами, где они запатентовали некоторые инструкции, которые будут загружать / хранить слова, которые не выровнены по словам, а также некоторые вещи для динамического переключения между старшим и младшим порядковым номером. Это было оспорено в суде, когда MIPS подала в суд на производителя клонов MIPS, и MIPS выиграл (примерно в 2000 году). Но большинство патентов касаются архитектурных вопросов. К сожалению, вы не можете создать процессор, совместимый с существующими компиляторами, не копируя архитектуру и набор команд.
Пару дней назад я опубликовал и потом внезапно убрал в черновики статью о плане написать про создание своей ОС для архитектуры ARM. Я сделал это, потому что получил много интересных отзывов как на Хабре, так и в G+.
Сегодня я попробую подойти к вопросу с другой стороны, я буду рассказывать о том, как программировать микроконтроллеры ARM на нарастающих по сложности примерах, пока мы не напишем свою ОС или пока мне не надоест. А может, мы перепрыгнем на ковыряние в Contiki, TinyOS, ChibiOS или FreeRTOS, кто знает, их там столько много разных и интересных (а у TinyOS еще и свой язык программирования!).
Небольшой экскурс в архитектуру
ARM продвигает замечательную архитектуру, которую успешно лицензирует, мне на самом деле сложно представить, в каком устройстве нет никакого присутствия продуктов этой компании. В вашем смартфоне гарантированно есть несколько ядер на базе архитектуры ARM. Еще парочка найдется в современном ноутбуке (и это даже не CPU, а так, сопутствующий контроллер какой-либо периферии), еще несколько – в автомобиле. Есть они и в других бытовых вещах: микроволновках и телевизорах.
Такая гибкость достигается тем, что в самом базовом варианте ядро ARM очень простое. Сейчас существуют три разновидности этой архитектуры. Application применяется в устройствах «общего назначения» – как основной процессор в смартфоне или нетбуке. Этот профиль самый навороченный функционально, тут есть и полноценный MMU (модуль управления памятью), возможность аппаратно выполнять инструкции Java bytecode и даже поддержка DRM-схем. Microcontroller – это полная противоположность профилю application, применяемая (внезапно!) для использования в микроконтроллерах. Тут актуально минимальное энергопотребление и детерминистическое поведение. И, наконец, real-time используется как эволюция профиля microcontroller для задач, где критично иметь гарантированное время отклика. Все эти профили получили реализацию в одном или нескольких ядрах Cortex, так, например, Cortex-A9 основан на профиле application и является частью процессора в iPhone 4S, а Cortex-M0 основан на профиле microcontroller.
Железки!
В качестве целевой платформы мы будем рассматривать работу с Cortex-M, так как она самая простая, соответственно, надо вникать в меньшее количество вопросов. В качестве тестовых устройств я предлагаю вам LPC1114 – MCU производства NXP, схему на котором можно собрать буквально на коленке (нет, правда, вам нужен только сам MCU, FTDI-кабель на 3,3 В, несколько светодиодов и резисторов). LPC1114 построен на базе Cortex-M0, так что это будет самый урезанный вариант платформы.
В качестве альтернативного варианта мы будем работать с платформой mbed, а конкретно, с моделью на базе LPC1768 (а значит, внутри там Cortex-M3, несколько более навороченный). Вариант уже не настолько бюджетный, но процесс заливки бинарников на чип и отладки упрощен максимально. Да и можно поиграться с самой платформой mbed (вкратце: это онлайн-IDE и библиотека, с помощью которой можно программить на уровне ардуины).
Приступим
Интересной особенностью современных ARM-ов является то, что их вполне реально программировать целиком на С, без применения ассемблерных вставок (хотя ассемблер не так уж и сложен, у Cortex-M0 всего 56 команд). Хотя некоторые команды в принципе не доступны из С, эту проблему решает CMSIS – Cortex Microcontroller Software Interface Standard. Это драйвер для процессора, который решает все основные задачи управления им.
Как же загружается процессор? Типична ситуация, когда он просто начинает выполнять команды с адреса 0x00000000. В нашем случае процессор несколько более умный, и рассчитывает на специально определенный формат данных в начале памяти, а именно – таблицу векторов прерываний:
Старт выполнения программы происходит следующим образом: процессор читает значение по адресу 0x00000000 и записывает его в SP (SP – регистр, который указывает на вершину стека), после чего читает значение по адресу 0x00000004 и записывает его в PC (PC – регистр, который указывает на текущую инструкцию + 4 байта). Таким образом начинает выполняться какой-то код пользователя, при этом у нас уже есть стек, указывающий куда-то в память (т.е., все условия для выполнения программы на С).
В качестве тестового упражнения мы будем мигать светодиодом. На mbed у нас их целых четыре, в схему с LPC1114 (далее — «доска») мы устанавливаем светодиод вручную.
Перед тем как непосредственно писать код, нам надо выяснить еще одну вещь, а именно – что где должно располагаться в памяти. Поскольку мы не работаем с какой-то «стандартной» ОС, то компилятор (вернее, компоновщик) не может узнать, где у него должен быть стек, где сам код, а где — куча. К счастью для нас, у семейства ядер Cortex стандартизированная карта памяти, что позволяет относительно просто портировать приложения между разными процессорами этой архитектуры. Работа с периферией, конечно, остается процессорозависимой.
Карта памяти для Cortex-M0 выглядит вот так:
У Cortex-M3 она, по сути, такая же, но несколько более детальна. Проблема тут в том, что у NXP есть свой, отдельный взгляд на этот вопрос, так что проверяем карту памяти в документации на процессор:
На самом деле, SRAM у нас начинается с 0x10000000! Вот так, одни стандарты, другие стандарты, а все равно надо тома документации листать.
Вооружившись этими знаниями, идем писать код. Для начала – таблица прерываний:
Сохраним эту таблицу в boot.s . Тут, фактически, только одна ассемблерная вставка – функция hang, которая устраивает процессору бесконечный цикл. Все прерывания, кроме reset, указывают на нее, так что в случае непредвиденной ситуации процессор просто зависнет, а не пойдет выполнять непонятный участок кода.
Сама таблица должна бы быть длиннее, но на самом деле мы могли бы закончить ее еще после вектора Reset, остальные у нас не сработали бы в этом примере. Но, на всякий случай, мы заполнили таблицу почти целиком (кроме пользовательских прерываний).
Теперь напишем реализацию функции main:
У mbed первый светодиод подключен к порту GPIO 1.18, на доске мы подключили светодиод к GPIO 1.8. Одни и те же пины могут выполнять разные функции, эти по умолчанию работают именно как GPIO (General Purpose I/O – линии ввода/вывода общего назначения).
Код относительно прямолинеен, если держать под рукой LPC-шный User manual (один и второй). Для начала мы указываем режим работы GPIO через регистр GPIO_DIR_REG (у наших процессоров они в разных местах, да и вообще LPC1768 может работать с GPIO более эффективно), где 1 – вывод, 0 – ввод. Потом мы запускаем бесконечный цикл, в котором пишем в порт попеременно значения 0 и 1 (0 В и 3,3 В соответственно).
Функция для «паузы» у нас работает наугад, просто прокручивая относительно долгий цикл ( volatile int не дает компилятору выоптимизировать этот цикл целиком).
Наконец, все это нужно правильно скомпоновать:
Сценарий компоновщика объясняет ему, где у нас флеш, где оперативная память, какие у них размеры (тут используются размеры для LPC1114, так как у LPC1768 всего больше, сдвиги, к счастью, идентичны). После определения карты памяти мы указываем, какие сегменты куда копировать, .text (код программы) попадает в флеш, .bss (статические переменные, которых у нас пока нет) – в память. Помимо этого мы задаем два символа, которые использовали в boot.s: _stack_base – указывает на вершину стека и _boot_checksum (спасибо Zuy за уточнение!) – записывает чексумму загрузчика. Чексумма рассчитывается по формуле: дополнительный код (2's compliment) от суммы полей выше (т.е. адреса стека, и всех прерываний до непосредственно чексуммы). Хотя утилиты для прошивки (см. далее) сами исправили бы чексумму на правильную, если бы мы прошивали бы код из самого приложения, то загрузиться снова мы бы уже не смогли.
Теперь у нас есть три файла: boot.s, main.c, mem.ld, пора это все скомпилировать и, наконец, запустить. В качестве тулчейна мы будем использовать GCC, позже, возможно, я покажу как делать то же с LLVM. Пользователям OS X я советую взять тулчейн у Linaro – в самом конце списка: Bare-Metal GCC ARM Embedded. Пользователям других ОС я советую взять тулчейн там же :-) (разве что гентушникам будет проще сэмержить crossdev и скомпилить GCC).
Интересный момент тут — это отключение использования всех стандартных библиотек у GCC. Действительно, весь код, который попадет в итоговый бинарник – это код, который написали мы сами.
Вопрос: как компоновщик знает, куда надо засунуть таблицу прерываний? А он и не знает, там не написано :-). Он просто линкует подряд, начиная с нулевого адреса, так что порядок файлов (boot.o, потом main-c0.o) очень важен! Попробуйте слинковать наоборот или слинковать boot.o два раза и сравните вывод в lst-файле.
Хорошая идея – посмотреть на итоговый листинг (файл lst) или закинуть бинарник в дизассемблер. Даже если вы не говорите на ARM UAL, то чисто визуально можно проверить, что хотя бы таблица прерываний находится на своем месте:
Еще можно обратить внимание на забавный момент – GCC при компиляции под Cortex-M3 генерирует функцию wait() больше, чем в варианте под Cortex-M0. Правда, если включить оптимизацию то она вправит ему мозги.
Мигаем!
Все что нам осталось – залить бинарники на наши тестовые платформы. С mbed тут все максимально просто, просто скопируйте blink-c3.bin на виртуальную флешку и нажмите reset (на mbed). С доской все немного сложнее. Во-первых, для того, чтобы попасть в загрузчик, нам нужен резистор между GND и GPIO 0.1. Во-вторых, необходима программа для непосредственно прошивки. Можно использовать Flash Magic (Win, OS X), можно использовать консольную утилиту – lpc21isp:
- ставим резистор между j5 и j7 (10 кОм подойдет);
- нажимаем reset;
- запускаем lpc21isp;
- снимаем резистор;
- нажимаем reset еще раз – запускается приложение.
Если у вас есть возможность запустить примеры на разных устройствах, вы заметите, что скорость мигания на них не идентична. Это связанно с тем, что у разных устройств разная частота ядра, соответственно, wait() они выполняют за разное время. В следующей части мы изучим вопросы осцилляции детальнее и сделаем четкий отсчет времени.
P.S. Отдельное спасибо хабраюзеру pfactum за то, что тратит время на исправление моих ошибок в тексте :-).
P.P.S. Просьба тем, у кого есть тестовая платформа на базе ARM – пишите в комментариях – какая. Я могу пересмотреть аппаратную базу для дальнейших статей.
Мощность современных процессоров растёт, как в стационарных компьютерах, так и в различных embedded устройствах, на борту которых процессоры на базе ARM с операционной системой linux. Сегодня в рамках данной статьи мы запустим эмулятор процессора ARM на x86 компьютере и в нём попробуем собрать Qt из исходников и тестовое приложение, т.е. так сказать сиэмулируем сборку ARM приложения.
В первой части статьи будем использовать эмулятор QEMU для aarch64, во второй части запустим эмулятор Raspberry и проверим работоспособность приложения в нём.
От себя хочу отметить, это все делается не быстро, и если Вы попробуете все это выполнить, то полный цикл займет у вас несколько дней!)
42 thoughts on “ARM. Учебный курс. IAR EWARM. Создание проекта.”
можно еще через встроенный USB по DFU прошивать без использования всяких преобразователей;)
Популярные теги
Нас же сейчас интересует среда для разработки приложений для архитектуры ARM, в частности Cortex-M3. Есть в их ассортименте и такой продукт и называется он EWARM, что является сокращением от Embedded Workbench for ARM, что в свою очередь, в моем вольном переводе на великий и могучий, звучит примерно как «Среда разработки для встроенных систем на архитектуре ARM», впрочем, за точность я не ручаюсь…
Данная среда поддерживает большое количество микропроцессоров и микроконтроллеров построенных на базе архитектуры ARM разных версий. Полный список можно посмотреть на их сайте Т.к. это серьезная среда разработки, то она поддерживает различные отладочные интерфейсы и средства сопряжения как производства самой IAR так и сторонних компаний, имеет встроенный отладчик, симулятор и т.д.
Но по причине отсутствия у меня какого либо девайса для внутрисхемной отладки рассказать я про все это не могу. А пользоваться симулятором как-то в голову даже не приходило. Я по старинке, пишу, заливаю в контроллер и смотрю что происходит. (Зато их есть у меня. И я вам скоро выдам пример того, какой это рулез. прим. DI HALT)
Есть мнение, что компилятор С/С++ у IAR один из самых лучших, но за это я не ручаюсь, хотя кое какие мои сравнения с Keil uVision v3 показали его превосходство.
Сколько стоит данное чудо я, к сожалению, на их официальном сайте найти так и не смог, а лазить по сайтам дилеров как-то недосуг… На наше счастье, данный продукт доступен в демо режиме для ознакомления. (Я тоже полазил, не нашел. Кейл стоит около 3 килобаксов. IAR, думаю, в тех же пределах. Вполне подьемно для коммерческого применения прим. DI HALT)
И здесь есть 2 варианта
- 1. Полнофункциональная версия с ограничением использования в 30 дней.
- 2. Версия без ограничения по времени использования но генерирующая код не более 32Кб. Под наши ковыряния хватит с лихвой.
Обе версии, кроме того имеют следующие ограничения:
- Они не включают исходный код библиотек.
- Они не включают поддержку MISRA C (что это такое, к сожалению не знаю).
- Имеют ограниченную техническую поддержку.
- Версия с ограничением кода в 32Кб не имеет поддержки расширенной отладки (что это такое, к сожалению не знаю)
Ну и как всегда есть вариант найти на просторах сети дистрибутив включающий все, что нужно для снятия этих ограничений.
Итак, выбираем для себя вариант, который подойдет больше всего, скачиваем и устанавливаем. Здесь вопросов возникнуть не должно, все тривиально.
После установки можно приступать к созданию проекта. Запускаем IAR Embedded Workbench и видим следующее окно:
Лирическое отступление.
Если кто-то, как я, привык для копирования/вставки использовать сочетание клавиш Ctr+Insert/Shift+Insert, то его ждет засада! EWARM по умолчанию понимает только Ctrl+C/Ctrl+V и при нажатии Ctr+Insert или Shift+Insert только меняет режим вставки/перезаписи текста. Почти месяц меня это жутко бесило, пока однажды мне не стукнуло что-то в голову и не пришла мысль порыться в настройках… Оказалось, что это легко лечится путем назначения сочетаний клавиш командам! Делается это во вкладке меню Tools->Options, далее Keybindings.
Выбираем в меню:
Project->Create New Project
Открывается окошко создания нового проекта.
На данном этапе можно выбрать из шаблонов, что именно мы хотим создать, но выбор там не велик, а все шаблоны содержат пустые заготовки файлов с нужным расширением и заголовками. Поэтому не ломаем голову а выбираем
и жмем кнопочку ОК
Появится диалог выбора имени проекта и указания, куда его сохранить. Называем проект милым вашему сердцу названием и сохраняем в укромном месте. Я же назвал его LEDTest, что какбы намекает… В итоге получаем следующую картину:
Создался новый проект содержащий только один файл main.c который содержит только одну пустую функцию main(). А вы хотели большего? Дальше все ручками.
На данном этапе желательно нажать на кнопку с изображением трех дискеток или через меню
EWARM попросит ввести имя WorkSpace (воркспейс может содержать множество проектов) и не мудрствуя лукаво я назвал его также LEDTest.
В отличие от Keil’a EWARM не попросил указать целевое устройство и все остальное, поэтому лезем в свойства проекта и начинаем его настраивать.
По аналогии с Microsoft Visual Studio EWARM позволяет создавать произвольное число конфигураций и по умолчанию создает в проекте 2 конфигурации Debug и Release, что подразумевает 2 набора параметров, одни для компиляции кода содержащего отладочную информацию и другой для кода без нее. Выбираем наиболее подходящую для себя.
Я, например, сразу выставляю Release и настраиваю только ее, но это дело вкуса и наличия или отсутствия у вас средств отладки.
Итак, идем в меню
Либо нажимаем Alt+F7, либо тыкаем правой кнопкой мыши на корне дерева слева и выбираем в меню Options. Появляется окно настроек проекта.
Первая категория – General Options
Здесь желательно выбрать ядро для которого нужно откомпилировать код или указать конкретное устройство. По умолчанию указано ядро ARM7TDMI. Переключаем радиобуттон на Device, нажимаем на кнопку справа от поля ввода и в списке выбираем
, где Y соответствует семейству имеющегося у вас микроконтроллера. Я выберу ST STM32F10xxE.
Далее по вкладкам и категориям буду пробегаться кратко и без картинок т.к. вкладок много и не все они важны для нас на данном этапе. На существенных остановлюсь подробно.
Output (вывод)
Здесь указываем что мы хотим получить навыходе, исполняемую программу или библиотеку. Оставляем без изменения – Executable. Также здесь можно прописать пути куда ложить откомпилированную программу/библиотеку, объектные файлы и файлы листингов. Меняем, если душа того просит.
Library Configuration (конфигурация runtime библиотеки языка С). Это тема отдельной телепередачи :-) но сейчас можно смело поставить None и пройти дальше.
Library options (опции стандартной библиотеки языка С)
Здесь настраивается работа функций printf и scanf. Вернее поддержка различных ключей строки форматирования. Ниже кратко расписано какая опция что поддерживает, а более подробно можно прочитать в документации идущей в комплекте с EWARM. Поддержка более сложных ключей форматирования увеличивает размер кода т.к. обработчики строки форматирования разные по сложности реализации. В данном проекте нам это не важно т.к. данными функциями мы пользоваться не будем. А в последущием я освещу данный вопрос подробнее.
MISRA-C: 2004 и MISRA-C: 1998. Настройки расширений MISRA-C. Что это такое, я честно не знаю. :-)
C/C++ Compiler (настройки компилятора С/С++)
Здесь настраивается поддержка расширений языков С/С++, режимы оптимизации компилятора, генерация отладочной информации, пути к инклудам и т.д. Здесь пока можно ничего не трогать.
Assembler
Соответственно настройки языка ассемблера. Здесь пока можно ничего не трогать.
Output Converter (конвертация вывода)
Вот это нам нужно. Дело в том, что по умолчанию EWARM генерирует исполняемый файл в формате ELF, что какбы намекает, что Unix и прочие линуксы IAR’у не чужды.
Но нам то они ни к чему, поэтому смело тыкаем галку Generate additional output (генерировать дополнительный выходной файл) и в списке Output format (формат выходного файла) выбираем подходящий для себя, вернее для используемого вами программатора, формат.
Выбор особо не велик и реально для большинства будет состоять из двух вариантов: Intel extended, в простонародье именуемый HEX или binary. Я лично пользуюсь вариантом binary. Здесь же, если того требуют ваши религиозные убеждения, можно задать имя выходного файла отличающееся от дефолтного.
Custom build (пользовательская сборка)
Здесь можно задать дополнительные утилиты и их параметры которые будут использоваться при сборке проекта, но нам это ни к чему — пропускаем.
Build Actions (действия при сборке)
Здесь можно указать команды которые нужно выполнить перед сборкой или после. Поступаем аналогично предыдущему пункту.
Категория Linker (линковщик)
Вот и добрались до второго, после указания целевого устройства, важного момента! Ибо от линковщика, вернее его настроек, очень сильно зависит запуститься ваш проект в микроконтроллере или нет т.к. именно линковщик располагает код и различные таблицы (например векторов прерываний) по нужным адресам.
Вкладка Config (конфигурация). Здесь содержится ссылка на используемый файл конфигурации линковщика. Это очень важный файл т.к. именно в нем прописана конфигурация нашего микропроцессора в части памяти (ее наличия или отсутствия, адресации и размера), размещения таблицы векторов прерываний, размеры стека и кучи. По умолчанию проставлена ссылка на файл конфигурации идущий в комплекте с EWARM’ом и едином для всех устройств на базе ядра Cortex, что не есть хорошо, т.к. устройства все разные, объемы флеша и ОЗУ у них разные и т.д. К счастью, есть возможность отредактировать этот файл самостоятельно, что дает широчайший простор творчеству, либо с использованием кнопки Edit… находящейся здесь же.
Самостоятельная конфигурация файла настроек линковщика, занятие бесспорно увлекательное и плодотворное, но оно выходит далеко за рамки данной статьи т.к. только об этом можно написать не одну статью. Подробно все описано в руководстве пользователя, идущем в комплекте с EWARM. Скажу лишь, что там можно создавать сегменты памяти, указывать их тип, размер, размещение и еще много чего. Иногда это очень нужно, но это уже в более серьезных проектах.
Поэтому ограничимся нажатием кнопочки Edit… Правда перед этим нужно решить один концептуальный вопрос.
Дело в том, что как я уже сказал выше, данный файл является заготовкой для всей архитектуры Cortex, поэтому если вы его измените, а потом захотите создать проект для другого контроллера, того-же NXP LPC17XX, то его опять придется редактировать уже под этот процессор. Тут есть 3 варианта решения:
- Сказать себе, что кроме STM32F меня ничего не интересует и отредактировать данный файл.
- Скопировать данный файл в той-же папочке где он лежит (а лежит он, как можно догадаться, в папке диск:путь куда установили EWARM\arm\CONFIG\) во что-то типа STM32F10XXX.icf и редактировать его.
- Скопировать его в папочку с проектом переименовав во что-то типа STM32F10XXX.icf и редактировать его.
Итак, выбираем вариант себе по душе (я лично пользуюсь 3-им вариантом а путь прописываю так:
Переменная $PROJ_DIR$ разворачивается в путь до папки с проектом автоматически, т.е. путь получается относительным. Таким образом можно папку с проектами копировать потом куда угодно и файл не «потеряется» в отличие от использования жесткого пути), выбираем свой файл отредактировав путь или нажав кнопку выбора файла (кнопка с «…» справа от едита) и нажимаем кнопку Edit…
В появившемся окошке в первой вкладке Vector Table задаем адрес таблицы векторов прерываний. Что это такое, для тех кто не в курсе, я не буду раскрывать. (Я тоже не скажу :), т.к. все уже сказано в разделе про AVR. Тут все точно также, только векторов больше. прим DI HALT)
Адрес может быть либо 0х00000000 либо 0х08000000. Я предпочитаю ставить 0х08000000 т.к. он указывает на начало внутренней флеш памяти, а адрес 0х00000000 может мэпиться на флешку а может и нет, в зависимости от состояния входов BOOT в момент инициализации контроллера, но это нужно уже курить даташит на устройство.
Вкладка Memory Regions (регионы памяти).
Здесь задается 2 важных для работы контроллера вида памяти ROM (ПЗУ) и RAM (ОЗУ) вернее их адреса начала и окончания. ROM — это наша внутренняя флеш память. Начинается она с адреса 0х08000000, это заложено в архитектуре контроллера. А вот заканчивается у каждого по разному. Зависит от объема который есть в вашем контроллере.
У меня ее 512Кб, а у вас может быть 32, 64, 128, 256. Т.е. адрес окончания этой области памяти вычисляете сами. Для меня он будет равен 0x0807FFFF (адрес начала 0x08000000 + размер флеша (512*1024) – 1 в шестнадцатеричном формате). Для вас это может быть 0x08007FFF, 0x0800FFFF, 0x0801FFFF и т.д. Желательно указывать точный размер чтобы полученная прошивка не превысила этот размер, а так линковщик ругнется в случае чего. Но нам это не грозит пока. Аналогично заполняем поля для RAM, зная из чтения даташита, что она начинается с адреса 0x20000000 и посчитав где она закончится.
Если ошибетесь в этих адресах, особенно начальных, например нолик пропустите или лишний напишите, то программа просто не будет работать.
Вкладка Stack/Heap Sizes (размеры стека и кучи)
Параметры говорящие сами за себя.
Стек нужен для передачи параметров функциям, сохранения точек возврата из них и т.д. Сильно большим его делать не имеет смысла т.к. зря будет расходоваться ОЗУ, а если сделать сильно маленьким, то может не хватить (особенно если будет использоваться много вложенных функций). Поставим его равным 0x200 т.е. 512 байт. В нашем проекте этого более чем достаточно.
Куча – это часть ОЗУ выделенная для функций работы с памятью языка С/С++ таких как malloc, оператор new и т.д. В данном проекте мы их использовать не планируем, поэтому ставим 0.
Все, нажимаем кнопочку Save.
В остальных вкладках категории Linker настраиваются подключаемые внешние библиотеки, пути к ним, настройка имени выходного файла, настройки генерации листингов, расчета контрольных сумм и т.д. Нам в данном проекте ничего из этого не понадобиться, а объяснять все слишком долго. Будут конкретные вопросы — спрашивайте в комментах.
Категория Debuger (отладчик)
Здесь настраиваются аппаратные средства внутрисхемной отладки либо отладка в симуляторе. Как я уже говорил, аппаратных средств у меня нет, а симулятором я не пользуюсь. Поэтому рассказать тут особо ничего не могу.
С облегчением жмем кнопку Ок справа-внизу окошка, и применяем выбранные параметры.
Теперь можно смело нажать кнопку F7 или в меню
и откомпилировать наш проект.
В папочке которую вы указали для выходных файлов программы (если ничего не меняли, то это будет, в зависимости от выбранной конфигурации, папка Debug/exe либо Release/exe в папке с проектом) увидим 2 файла. Один с раширением .out и второй .bin или .hex, в зависимости от того, что вы указали в качестве дополнительного выходного файла.
Все, наша первая программа готова! Можно прошивать ее в контроллер и она заработает! Не верите? А вы попробуйте.
На этом позвольте закончить мою первую статью т.к. она и так получилась не маленькой. А к написанию более функционально насыщенной программы мы перейдем на следующем нашем шаге.
Спасибо. Вы потрясающие! Всего за месяц мы собрали нужную сумму в 500000 на хоккейную коробку для детского дома Аистенок. Из которых 125000+ было от вас, читателей EasyElectronics. Были даже переводы на 25000+ и просто поток платежей на 251 рубль. Это невероятно круто. Сейчас идет заключение договора и подготовка к строительству!
А я встрял на три года, как минимум, ежемесячной пахоты над статьями :)))))))))))) Спасибо вам за такой мощный пинок.
Заключение
Собирать приложения для ARM возможно на x86 устройствах, используя эмулятор QEMU. Я думал, что напишу данную статью за одну неделю, но процесс затянулся практически на три недели, потому что каждый из этапов длится очень долго (установка системы, обновление системы, установки dev пакетов, а так же получение исходных кодов Qt из гитхаб). К примеру сборка static версии Qt в эмуляторе Raspberry занял у меня 1426 минут.
А можно ли быстрее?Да, это называется Cross build. Для этого конфигурируют sysroot, устанавливают компилятор для ARM, конфигурируют и собирают Qt в вашей host системе. Потом настраивают QtCreator на использование данной версии Qt и собирая приложение на своём компьютере/ноутбуке x86, получают версию, которая будет работать в embedded linux. ссылка 1 ссылка 2 Т.к. это уже выходит за рамки данной статьи, возможно я напишу и про это, если у меня появится время или вдохновение, но может быть кто-то и другой напишет, как это сделать для последней версии Qt 5.15.
Ну повторюсь, если кто-то захочет повторить действия из второй главы для эмулятора ARM Raspberry, то можете написать, сколько времени происходит у Вас сборка qmake и этап конфигурирования с указанием вашего процессора в комментариях.
У меня есть несколько вопросов о том, как я создам свой собственный процессор на основе ARM?
Вот как это делают компании:
- Поднимите около 10 миллионов долларов США.
- Соглашайтесь с ARM, чтобы получить лицензию. Это, вероятно, будет стоить не менее 1 миллиона долларов США.
- Получить файлы дизайна из ARM. Вероятно, это будет в какой-то форме VHDL, Verilog или «зашифрованный» список соединений.
- Создайте свой собственный чип, используя сочетание вашей собственной логики (для периферийных устройств) и то, что ARM дал вам. На этом этапе, вероятно, потребуется некоторое дорогостоящее программное обеспечение САПР и небольшая группа экспертов. Ожидайте потратить не менее 5 миллионов долларов США и несколько лет.
- Получить маски для самого чипа. Если вы используете какой-либо современный полупроводниковый процесс, то это будет стоить около 1 миллиона долларов США.
- Получить сам чип. Цена варьируется, но должна быть меньше 0,5 млн. Долл. США.
- Отлаживайте созданный чип, исправляйте ошибки, а затем возвращайтесь к шагу 5, пока не получите что-то, что вы можете продать.
Вот как ВЫ :
- Пройдите курс компьютерного дизайна на уровне выпускников в вашем местном университете.
- Возьмите больше курсов цифровой логики и всего остального.
- Создайте процессор с нуля в VHDL или Verilog.
- Создайте другой процессор с нуля.
- Посмотрите на набор команд ARM и спроектируйте совместимый процессор.
- Сделайте ваш ARM-совместимый процессор работой в FPGA.
- Не распространяйте исходный код VHDL /Verilog, если вы не хотите, чтобы вас привлекали.
- Используйте свой опыт ARM для написания хорошей диссертации для вашего PhD.
- Используйте свою кандидатуру для работы в ARM, или TI, или кто бы то ни было. Затем повторите процесс, используя предыдущие 7 шагов по тому, как компания это делает.
Хорошо, поэтому этот список немного застенчивый, но он в основном правильный. Дело в том, что даже не обращайтесь к ARM напрямую, потому что у вас нет денег. И не делайте ничего, что может заставить вас подать иск в ARM.
ARM имеет Программу развития университета в университете . Как студент, вы можете получить доступ к основному материалу Cortex-M0. Но если вы действительно заинтересованы, привлеките свою участь, а затем вы сможете получить доступ к гораздо большему количеству материалов для разработки (Verilog FPGA code, Evaluation IP, Simulations и т. Д.).
Взгляните на это ядро ARM на OpenCores.
ARM Cortex-M1 (возможно, самый простой из ARM-процессоров) - это первый ARM-процессор, специально разработанный для реализации в качестве мягкого процессора в FPGA. Он оптимизирован для следующих типов FPGA :
Сама ARM создает Cortex -M1 Development Kit для Altera Cyclone III , хотя это немного дороже в $ 625 от DigiKey . Вы все же получаете все ARM Cortex-M1 IP и лицензию на разработку (плюс бесплатный грант на 1000 плат для тех, кто собирается в производство, довольно круто).
Возможно, есть некоторые варианты для получения IP-адреса (возможно, у них есть учебная программа, кто-то упомянул университетскую программу, но это было для M0). Тогда вы могли бы купить доску разработки отдельно.
Вот некоторая информация о поместив ARM Cortex-M1 на FPGA Actel.
Между тем есть некоторый интерес к другим версиям ARM Cortex на FPGA; вот статья от кого-то, кто реализовал ARM Cortex- M0 на FPGA Xilinx.
Теперь вы можете получить доступ к процессору Cortex-M3 (и расширяемой подсистеме AHB /APB) через программу ARM DesignStart.
Опция Eval обеспечивает цель FPGA (поддерживается симуляция, с запутанным RTL ядра, все остальное в Verilog). В настоящее время это предназначено для ARM MPS2 + FPGA с поддержкой mbed.
Версия Pro (доступна только для компаний /университетов, которые могут подписывать лицензию) позволяет производить и включает ядро процессора в Verilog (это охватывает как Cortex-M0, так и Cortex-M3).
2. Запускаем в эмуляторе Raspberry
Так как в рамках данной статьи мы эмулируем ARM процессор, значит запускать будем тоже в виртуальной машине ссылка 1 ссылка 2 ссылка 3:
Скачиваем официальный образ с сайта Raspberry, ядро для эмулятора и запускаем (я создал такой запускной файл):
Пробуем запустить наше приложение:
Почему так? Смотрим процессор:
Смотрим файл конфигурации в CentOS:
Ну что же, мы собрали приложение для armv8 64 битное, и пытаемся запустить его в 32 битном эмуляторе с процессором armv6. Надеюсь, что владельцы реальных устройств с новыми 64 битными процессорами смогут отписаться в комментариях, получилось ли у них запустить приложение на реальном устройстве или нет.
Ну что же, не беда, мы же можем теперь собирать и в эмуляторе Raspberry? Обнаруживаем, что у нас очень мало свободного места на диске, после вызова команды df -h. Наиболее простой способ оказался скопировать файл образа, его увеличить, стартануть виртуальную машину с двумя файловыми системами, увеличив корневой раздел на второй машине, и после этого использовать второй образ. Поехали:
В скрипт запуска добавьте еще один жесткий диск:
-hdc 2020-05-27-raspios-buster-armhf-10gb.qcow2
После запуска отредактируйте этот жесткий дискsudo cfdisk /dev/sdc:
Write и подтверждение yes:
Не забываем проверить, что диск у нас стал нужного нам размера:
Что-то размер диска sdc, подключенного к папке /test не добавился, давайте это исправлять:
Выключаем виртуалку. Снова редактируем файл start-emul.sh, заменив жесткий диск hda на новый, и удалив ссылку на третий жесткий диск -hdc. Теперь у нас файловая система с большим пространством.
Теперь мы можем подключить жесткий диск с исходниками Qt от первой виртуалки.
Совет: лучше всего «зачистить исходники» от временных файлов, т.е. вернуть наше состояние гит, которое было на момент клонирования репозитария перед конфигурированием:
Итак в Debian нам потребуются:
Так же получив ошибки:
Совет. Вы набирали эти команды в графическом окошке QEMU? Не забывайте, у нас же есть ssh: нужно стартануть в виртуалке ssh server: sudo systemctl start ssh && sudo systemctl enable ssh и подключаться к виртуалки с локального компьютера ssh pi@localhost -p 5022 пользователь pi пароль raspberry
Установим еще dev пакеты:
time ./configure -skip qt3d -no-warnings-are-errors -release -recheck-all -prefix /Qt/5.15.0 -opensource -confirm-license -nomake examples -nomake tests -c++std c++17 -I /usr/include/xcb/ -L /usr/lib/x86_64-linux-gnu/ -xcb-xlib -xcb -feature-thread -feature-xkbcommon -qt-libpng -qt-libjpeg -qt-zlib -I /usr/include/xcb/ -L /usr/lib/x86_64-linux-gnu/ --recheck-all -skip wayland -skip qtwebengine -skip qtwayland
. Done.
Info: creating super cache file /30/qt5/.qmake.super
Info: creating cache file /30/qt5/.qmake.cache
Info: creating stash file /30/qt5/.qmake.stash
This is the Qt Open Source Edition.
You have already accepted the terms of the Open Source license.
Running configuration tests…
…
Note: Option 'cache_use' with value 'none' was specified twice
Note: Also available for Linux: linux-clang linux-icc
Note: Disabling X11 Accessibility Bridge: D-Bus or AT-SPI is missing.
WARNING: QDoc will not be compiled, probably because libclang could not be located. This means that you cannot build the Qt documentation.
Either ensure that llvm-config is in your PATH environment variable, or set LLVM_INSTALL_DIR to the location of your llvm installation.
On Linux systems, you may be able to install libclang by installing the libclang-dev or libclang-devel package, depending on your distribution.
On macOS, you can use Homebrew's llvm package.
On Windows, you must set LLVM_INSTALL_DIR to the installation path.
Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into '/Qt/5.15.0'.
Prior to reconfiguration, make sure you remove any leftovers from
the previous build.
real 91m49.471s
user 78m43.608s
sys 7m22.934s
Те, кто дочитал до данного места и у кого остался еще энтузиазм попробовать это, было бы интересно получить Ваш FPS результат скорости выполнения этапа конфигурирования с описанием процессора, на котором Вы запускали. Данный результат, это запуск на Intel Core i5 7th Gen. Для эксперимента перед запуском, выполните совет по «зачистке» исходников из предыдущей графы статьи.
Теперь 1 ядро вашего компьютера будет очень много времени собирать Qt и возможно соберёт, а возможно появится ошибка, что не хватает памяти или ошибка при сборке. Для этого рекомендую создать файл подкачки на 1-1,5 Gb и подключить его:
Собираем и устанавливаем:
Если необходимо дополнительные модули, тогда мы всегда можем их дособрать, например для qtquickcontrols2:
После этого собираем приложение, и запускаем его:
Собираем из исходников Qt на CentOS ARM
Для установки на хост системе нам потребуется установить эмулятор QEMU. В Debian based дистрибутивах это пакет qemu-system-arm. Для управления виртуальной машины в графическом режиме можно установить virt-manager.
После запуска создаем виртуальную машину:
Задаём количество процессоров и оперативной памяти:
Задаём размер системного диска:
Финальные настройки, выбор сети:
Для тех, кто хочет загружать или устанавливать оффлайн, есть образ диска:
Сборку будем совершать на втором виртуальном диске, для этого нам достаточно будет диска на 25-30 Gb. Создаем новый жесткий диск, выключив виртуальную машину и подключив его к ней и после этого запускаем снова. Разобьем наш жесткий диск и отформатируем:
Вы можете использовать файловую систему XFS, но тогда Вы не сможете использовать этот файл жесткого диска в виртуалке эмуляторе Raspberry, т.к. в ней ядро собранно без поддержки файловой системы XFS.
После установки, подключаемся в виртуальную машину и устанавливаем необходимые нам пакеты:
Повторяем запуск конфигурирования и получаем:
Установим компилятор и снова конфигурируем:
Ищем и доставляем необходимые пакеты:
Конфигурируем, и получаем уже одну ошибку:
Добавляем еще пакетов и смотрим лог конфигурирования:
Ну что же, всё готово, но нужно проверить опции, которые возможно нам пригодятся:
Придётся нам собрать OpenSSL и потом уже собирать Qt из исходников:
Дальше снова конфигурируем Qt и запускаем его сборку командой make или make -j4, согласно количеству процессоров (если вы решили создать VM с 4м процессорами), которые заданы в настройках виртуалки.
Сборка приложения падает на:
Устанавливаем допонительные версии пакетов и с попытки 3 у нас это получается:
- yum install harfbuzz-devel
- yum install at-spi2-atk-devel at-spi2-core-devel dbus-devel glib2-devel graphite2-devel keyutils-libs-devel krb5-devel libcom_err-devel libicu-devel libselinux-devel libsepol-devel libverto-devel pcre-devel zlib-devel
- yum install mesa-libGLw-devel
Похожие вопросы
Читайте также: