Как использовать ассемблер в ардуино
Мне поручили университетский проект по созданию светодиодов, реагирующих на звук и звук, с использованием языка ассемблера. Я уже сделал код C++ в arduino, который использует библиотеку Fastled. Как мне написать рабочий код для этого проекта на ассемблере (не ограничиваясь IDE arduino, но предпочтительнее). Я уже пытался преобразовать свой код в сборку с помощью онлайн-конвертера, но это бесполезно.
@COAL, 👍0
4 ответа
Вы должны использовать ключевое слово asm
, например:
asm("sei \n")
В вашем случае рекомендуется использовать определения, например
#define CLI() asm("cli \n")
#define noInterrupts() cli()
#define SEI() asm("sei \n")
#define interrupts() sei()
Подробнее см. на странице arduino-inline-assembly-tutorial-1.
Среда Arduino IDE весьма своеобразна. Это не позволит вам работать над
проект, в котором нет файла с расширением «.ino». С другой
стороны, ему все равно, сколько кода в этом файле, и вы можете
держите его счастливым, создав пустой файл .ino. Я рекомендую, однако, что
вы поместите хотя бы блок комментариев в этот файл, чтобы сделать вещи
меньше путаницы для других людей, которые могли видеть ваш проект. Тогда ты можешь
поместите свой ассемблерный код рядом с этим пустым файлом в собственные файлы
заканчивается расширением «.S». Эти файлы будут предварительно обработаны перед
собирается, поэтому вы можете #include <avr/io.h>
и использовать макросы
определенные в нем для портов ввода-вывода, битов и т. д.
Проект будет выглядеть следующим образом:
my_project/ # содержащий каталог
├── my_project.ino # только комментарии, чтобы IDE была счастлива
├── my_project.S # основной файл сборки
└── some_extras.S # возможно больше файлов сборки...
Если весь проект представляет собой чистую сборку, один из ваших файлов сборки должен
определить символ с именем main
, который является точкой входа в программу:
.global main
main:
; код начинается здесь
Если вы собираетесь смешивать ассемблер и C++, вы можете определить main()
в файле .ino и вызывайте оттуда свои процедуры сборки, которые
должен быть объявлен как extern "C"
:
extern "C" void my_assembly_routine();
int main()
{
my_assembly_routine();
}
Помните о соглашениях о вызовах при смешивании asm и C++.
Если вы собираетесь использовать базовую библиотеку Arduino, вам следует определить
setup()
и loop()
вместо main()
. После этого ядро Arduino
предоставить свой собственный main()
, который позаботится о его инициализации.
Если вы собираетесь писать в основном на C++, добавляя лишь немного ассемблера тут и там встроенная сборка может быть лучшим вариантом. Cf Мишель Ответ Кейзерса.
Проголосовал, много новой информации для меня тоже., @Michel Keijzers
Извините.
Основной обучающий эффект этого упражнения — "Не делайте этого". Вы не превзойдете компилятор С++ по производительности (скорости). Но вы столкнетесь с большим количеством ошибок, чем можете себе представить.
Единственной целью языка ручного ассемблера внутри c/c++ является добавление наносекундного времени путем добавления некоторых операторов asm("nop");
для ожидания контролируемого небольшого числа тактов процессора.
Примеры @Michel Keijzers уже реализованы. Даже в удобной среде Arduino.
IMO, сложнее выйти за рамки программирования Arduino, перейдя непосредственно к аппаратному уровню микроконтроллера, работая с таймерами, другими компонентами микроконтроллера, регистрами и т. д. напрямую. На С/С++ конечно. Там вы узнаете, что помимо среды Arduino можно сделать гораздо больше.
Или: просмотрите скомпилированные результаты с помощью avr-objdump
, чтобы узнать, как эксперты компилируют C++ в машинный код. В конце концов, вы можете заметить, как вы можете помочь оптимизировать компилятор.
1. Изучая ассемблирование, вы узнаете намного больше, чем просто «не делайте этого»: вы получаете глубокое понимание того, что делают компилятор и аппаратное обеспечение, и вы узнаете, какие конструкции C/C++ компилируются в эффективный машинный код. Кроме того, вы должны хотя бы немного написать на ассемблере, чтобы по-настоящему оценить работу компилятора (вывод avr-objdump
). 2. Нередко avr-gcc производит неоптимальный код, который легко побеждается ручной сборкой. Я предполагаю, что этот вариант gcc не был так точно настроен, как ARM или x86\_64..., @Edgar Bonet
@ Эдгар Боне: Конечно, ты узнаешь гораздо больше. И только после того, как вы узнаете, что вы можете 1. оценить, что компилятор делает для вас 2. интерпретировать его результаты 3. решить, будете ли вы продолжать программирование на ассемблере. Кстати: я пришел из программирования на ассемблере, потому что FORTRAN был не совсем оптимален для небольших машин, и я счастлив, что кто-то изобрел C, а другие создали кросс-компиляторы., @DataFiddler
Re: «Основной обучающий эффект этого упражнения — «Не делай этого». Вам не победить компилятор C++..." Я согласен с Эдгаром Боне: (1) Arduino — это обучение, включая изучение программирования на ассемблере, аппаратного обеспечения и т. д. И ... (2) Да, вы можете превзойти компилятор C++, если немного попрактикуетесь. Например, цепочка инструментов GNU может вводить программу C++ и выводить соответствующий ассемблер. Это может быть очень поучительно для изучения ассемблера. Затем вы можете вручную создать любой фрагмент этого кода... сделать его быстрее или меньше. --o-0--
- Светодиод с кнопочным управлением Arduino со сборкой AVR
- Светодиод Arduino PWM с замиранием в сборке
- Сборка Arduino uno AVR со светодиодами
- Питание светодиодной ленты - Сколько ампер?
- Несколько условий оператора if
- Светодиоды: разница между общим анодом и общим катодом
- Светодиод L продолжает гореть
- Разные и самые быстрые способы вычисления синусов и косинусов в Arduino
Какую IDE мы должны использовать для этого? Кроме того, эти определения для встроенной сборки? Мы ограничены в том, чтобы основной рабочий код нашей программы был на ассемблере., @COAL
Для этого можно использовать стандартную среду разработки Arduino IDE. Вероятно, вам придется поместить код в функции настройки и цикла. Обратите внимание, однако, что Arduino IDE создает некоторый код вокруг установки и цикла (например, обработка прерываний)., @Michel Keijzers
Подожди здесь. Вы можете использовать #define для функций/методов? Ну, это для меня ново., @Agi Hammerthief