Написание прошивки:сборка или высокий уровень?

StackOverflow https://stackoverflow.com/questions/452139

  •  19-08-2019
  •  | 
  •  

Вопрос

Связанный с:

Если вы пишете код для микроконтроллер есть ли реальная разница, если вы пишете на ассемблере, C или каком-либо другом языке высокого уровня?Если бы вы написали код на C, как бы вы его скомпилировали?

Спасибо

Это было полезно?

Решение

Несколько комментариев:

1) Абсолютно не сборку, если этого не требуют ограничения производительности или оптимизации.Следующие показатели превосходны при сборке:

  • пришло время закодировать это
  • пришло время его отладить
  • пришло время проверить это
  • пришло время задокументировать это
  • время выяснить (1 год спустя), что именно вы делали, когда кодировали это
  • вероятность совершить ошибку

2) Я предпочел бы C ++, а не C для его инкапсуляции пространства имен и облегчения время компиляции объектно-ориентированные практики.C имеет слишком много возможностей для глобальных переменных и конфликтов пространств имен.(Java в реальном времени была бы хороша, но, насколько я понимаю, ее требования все еще довольно высоки)

Или, скорее, подмножество C ++:Исключайте исключения, виртуальные функции, идентификацию типа во время выполнения, а также динамическое выделение памяти в большинстве случаев - в основном все, что остается неуказанным во время компиляции, поскольку обычно это требует много дополнительных ресурсов во время выполнения.Это и есть "раздутие" C ++.

Я использовал компиляторы TI и IAR для C ++, для микроконтроллеров TMS320 и MSP430 (соответственно), и при надлежащих настройках оптимизации они выполняют фантастическую работу по снижению накладных расходов, которые вы могли бы ожидать от C ++.(Особенно, если вы поможете этому, разумно используя inline ключевое слово)

Я даже использовал шаблоны из-за некоторых их преимуществ во время компиляции, которые способствуют хорошему повторному использованию кода:например ,написание одного файла исходного кода для обработки 8-разрядных, 16-разрядных и 32-разрядных CRC;и полиморфизм во время компиляции чтобы позволить вам указать обычное поведение класса, а затем повторно использовать его, но переопределить некоторые из его функций.Опять же, компилятор TI имел чрезвычайно низкие накладные расходы при соответствующих настройках оптимизации.

Я искал компилятор C ++ для фотографий микрочипов;единственная компания, которую я нашел, которая производит его, - это IAR.($$$ было препятствием, но я надеюсь когда-нибудь купить копию) Компиляторы Microchip C18 / C30 довольно хороши, но они на C, а не на C ++.

3) Конкретное предостережение по поводу оптимизации компилятора:это может / сделает отладку очень сложной;часто невозможно выполнить оптимизированный код на C / C ++ за один шаг, и в ваших окнах просмотра могут отображаться переменные, которые не имеют корреляции с тем, что, по вашему мнению, они должны содержать в неоптимизированном коде.(Хороший отладчик предупредил бы вас, что конкретная переменная была оптимизирована из-за отсутствия существования или в регистр, а не в ячейку памяти.Многие отладчики этого не делают.>:(

Также хороший компилятор позволил бы вам выбирать оптимизацию на функциональном уровне с помощью #pragmas.Те, которые я использовал, позволяют вам указать оптимизацию только на уровне файла.

4) Сопряжение C-кода со сборкой:Обычно это бывает трудно.Самый простой способ - создать функцию-заглушку, которая имеет нужную вам подпись, например uint16_t foo(uint16_t a, uint32_t b) {return 0; }, где uint16_t = unsigned short, мы обычно делаем # of bits явным.Затем скомпилируйте его и отредактируйте созданную им сборку (просто не забудьте оставить части кода begin / exit) и будь осторожен не удалять какие-либо регистры без их восстановления после того, как вы закончите.

Встроенная сборка обычно может иметь проблемы, если вы что-то не делаете очень просто, как включение / отключение прерываний.

Подход, который мне нравится больше всего, - это встроенный в компилятор синтаксис "extended ASM".Компилятор Microchip C основан на компиляторе GNU C и имеет "расширенный ASM" который позволяет вам кодировать биты встроенной сборки, но вы можете дать ему множество подсказок, чтобы указать, на какие регистры / переменные вы ссылаетесь, и он обработает все сохранение / восстановление регистров, чтобы убедиться, что ваш ассемблерный код "хорошо работает" с C.Компилятор TI для TMS320 DSP не поддерживает эти;у него действительно есть ограниченный набор встроенных функций, которые имеют некоторое применение.

Я использовал assembly для оптимизации некоторого кода цикла управления, который часто выполнялся, или для вычисления sin(), cos () и arctan().Но в противном случае я бы держался подальше от ассемблера и придерживался языка высокого уровня.

Другие советы

Большинство производителей микроконтроллеров предоставляют своего рода кросс-компилятор, с помощью которого вы можете скомпилировать код на своем компьютере, а затем перенести его на микроконтроллер.

Почему C?
Преимущество C заключается в том, что в будущем ваш код будет легче переносить на другие микроконтроллеры.История вычислительной техники показала, что код обычно переживает аппаратные реализации.
Вторым преимуществом являются управляющие структуры (if, for, while), которые делают код более читаемым и обслуживаемым.

Почему именно язык ассемблера?
Вы можете вручную оптимизировать процесс создания.

Вердикт
Как это часто бывает с такого рода вопросами, компромиссы очень зависят от конкретного использования.
Имейте в виду, что часто можно смешивать эти два метода, выполняя вызовы assembly в коде C, так что вы сможете найти баланс, подходящий для вашего проекта.

Специфичный для аппаратного обеспечения PIC
IT кажется что у вас нет возможности GCC с большинством аппаратных средств PIC.С другой стороны, как отметил один из комментаторов, компилятором Microchip C30 для 16-разрядных PIC24 и dsPIC33 является gcc.
PIC также еще не поддерживается SDCC.
Новая информация:согласно комментарию, SDCC имеет работоспособную поддержку PIC.
Есть несколько других открытых исходных текстов Опции, но у меня нет опыта общения с ними.

Вероятно, лучшим вариантом является кодирование на C, а затем для очень немногих случаев, когда вам нужно выполнить ручную оптимизацию и вы можете выполнить работу лучше, чем компилятор, вам следует закодировать сборку в свои c-файлы.

Кодирование на ассемблере ушло в прошлое для ПК, но очень актуально во встроенных системах.

Запись сборки во встроенном режиме отличается от записи сборки на ПК.Компьютерные компиляторы "лучше людей" генерируют оптимизированные инструкции.Встроенные системы часто имеют странную архитектуру, а их оптимизирующие компиляторы далеко не так совершенны, как оптимизирующий компилятор для ПК.

Одна из проблем, с которой я столкнулся при написании assembly для микроконтроллера, заключается в необходимости очень будьте осторожны с тем, как был выложен ваш код.То, что таблица переходов пересекает границы памяти и заставляет ваш код переходить в действительно странные места, довольно тревожно.Кодируя на C, компилятор покрывает эту базу за вас.

Я бы определенно пошел с C.Это быстрее и создает более надежное программное обеспечение.Ассамблея может предложить очень мало и в редких случаях.Имейте в виду , что в C:

  • Вы смогли бы легко переносить код с существующих платформ, даже с ПК.
  • Вы можете разрабатывать на языке высокого уровня без ущерба для скорости выполнения или размера кода.При условии, что доступен качественный компилятор (для PIC18 есть много вариантов), они, скорее всего, были бы лучше для C, чем ручная сборка.
  • Гораздо проще отлаживать, тестировать и поддерживать код.C создает более надежный код.

Еще одна вещь, которая конкретно имеет отношение к PIC18.Вам не придется иметь дело с неинтуитивной архитектурой PIC и такими вещами, как банки памяти.

У меня был хороший опыт работы с IAR Компиляторы C для 8051-х годов в прошлом.

Мой недавний подход всегда был таким:-

Напишите это на C с помощью хорошего оптимизирующего компилятора, и ТОЛЬКО ТОГДА, если возникнут проблемы с размером или скоростью, рассмотрите возможность переписывания определенных частей на ассемблере.

Однако с тех пор, как я принял этот подход, я никогда необходимый написать одну строку ассемблера...

Дерзай на c !

Я работал на крупного производителя CE.Последний раз, когда я видел сборку, это было около 1996 года в некоторых небольших процедурах обслуживания прерываний для алгоритмов декодирования RC5 и RC6 и настройки телевизора.После этого всегда использовались c и C ++ (использовались только классы, никаких stl, исключений или rtti).У меня есть хороший опыт работы со старым компилятором KEIL для 8051 и с компилятором greenhills (MIPS) и набором инструментов VxWorks (на базе PowerPC).

Как говорит Родди, сначала напишите на C, а позже оптимизируйте в assembly (при необходимости).

Сборка во многих случаях может быть более быстрой;когда вы работаете на рабочем столе, компиляторы, как правило, оптимизированы до такой степени, что ручная сборка редко является необходимостью, но в мире uC это часто так.Кроме того, если вам нужно написать процедуры обработки прерываний и тому подобное, вы часто не можете сделать это на C.

Что касается компиляции, погуглите в поисках компилятора C для вашей цели.

Определенно C, за исключением случаев, когда

  • объем памяти программы крайне ограничен.Скажем, после кропотливой ручной оптимизации вашего кода на ассемблере вам удается уместить вашу программу в 1024 байтах флэш-памяти, при этом осталось 0 байт.В этом случае никакой компилятор C никуда не годится.

  • вы хотите иметь абсолютный контроль над временем.Если какая-либо задержка прерывания слишком велика, вам придется положиться на ассемблер.

Проблема в наши дни заключается в том, что встроенным может быть что угодно - от ATtiny с 6 выводами и несколькими байтами оперативной памяти до многоядерного SBC, работающего под управлением встроенной ОС, которая посрамила бы настольные компьютеры некоторых людей.

Таким образом, при выборе языка / среды разработки необходимо учитывать, насколько эффективным вам нужно быть в сравнении с тем, насколько сложна система.

Во-первых, C работает везде и довольно хорошо масштабируется, чем выше вы поднимаетесь, тем чаще вам придется вызывать внешние библиотеки и т.д.чтобы справиться со сложностью.

Для очень маленьких микросхем (измерение флэш-памяти в байтах) лучше всего использовать ASM, когда вы достигнете диапазона кб, можно использовать C или любой другой традиционный язык, поскольку вам не нужно считать каждый байт.Как только у вас появятся мегабайты для работы, у вас появится как возможность, так и все более вероятная потребность использовать RTOS, чтобы позаботиться обо всем и сократить время разработки.К тому времени, когда у вас будет оборудование, на котором вы сможете запускать полноценную ОС, вы, вероятно, сможете абстрагироваться от оборудования и просто записать все в расширенную ячейку, такую как Java или что-то подобное, не слишком беспокоясь о том, насколько все это ужасно расточительно и что вы больше не настоящий программист...;)

Исключением из вышесказанного является случай, когда вам нужна вся производительность, которую вы можете выжать из оборудования, и в этот момент вам, возможно, придется снизить ее на один-два уровня, чтобы сохранить эффективность.

Это суть, если вы используете C, вы можете вручную оптимизировать позже, я бы не использовал ничего, кроме C или ассемблера (никакого C ++ и т.д.).

Ключ - это набор команд микроконтроллера, если вы используете PIC или даже 8051, я бы использовал только ассемблер.Если это isa, дружественный к компилятору, такой как arm, avr или msp430, то используйте C для экономии набора текста, но по разным причинам у вас, вероятно, будут некоторые подпрограммы на ассемблере.Аналогично, вы, вероятно, захотите избежать библиотеки C, даже newlib может быть слишком громоздким, заимствуйте код или идеи из них, но не просто вставляйте их.О, возвращаясь к вопросу, посмотрите, какие компиляторы C доступны для целевого, опять же arm и avr, у вас не возникнет никаких проблем.Скорее всего, msp тоже в порядке.Просто потому, что Keil или Iar ПРОДАДУТ вам компилятор, не означает, что вы должны купить его или использовать, результат платных и бесплатных компиляторов может быть ужасным.В любом случае вам нужно хорошо разбираться в asm и изучить выходные данные (вероятно, для этого вам придется написать дизассемблер).

Итог (еще один итог), глобального ответа нет (ну, избегайте чего-либо выше, чем C - это глобальный ответ), это всегда зависит от того, что это за платформа, каковы ваши ресурсы, какова ваша задача, каковы требования к производительности, каковы требования к переносимости (если он действительно встроен в микроконтроллер, большая его часть по определению не переносима), какие компиляторы, отладчики, jtag и т.д. Доступны, даже если важным фактором может быть то, на какой операционной системе хоста вы разрабатываете.

Есть еще один момент, когда может потребоваться запись на ассемблере:если вам нужно выполнить какой-то низкоуровневый тест оперативной памяти или что-то подобное, что требует абсолютного контроля над тем, где хранятся данные.

Например, программное обеспечение, которое подтверждает СИЛ-2 (уровень целостности безопасности) и выше может потребовать постоянных проверок оперативной памяти, чтобы обнаружить любое возможное повреждение данных.Область оперативной памяти, которую вы проверяете, не может меняться во время ее проверки, и поэтому написание теста на ассемблере позволяет вам убедиться, что это верно, например, путем сохранения любых локальных переменных в определенных регистрах или в другой области оперативной памяти.Это было бы трудно, если не невозможно, в C.

Код запуска, который обнуляет оперативную память и инициализирует ненулевые статические переменные, также может быть написан на ассемблере для той же записи, хотя обычно такой код предоставляется.

Если вы пишете код, который сильно зависит от периферийных устройств, зависящих от конкретного устройства, и используемая вами цепочка инструментов не предоставляет необходимых встроенных компонентов для их эффективного использования (например, дерьмовый компилятор Freescale DSP563CC), тогда используйте assembly.

Кроме того, я думаю, что неписаные правила использования assembly vs.языки высокого уровня более или менее совпадают с языками для разработки программного обеспечения для настольных компьютеров:поддерживайте чистоту кода, его можно обслуживать и оптимизируйте горячий код с помощью машинного языка.

Код на языке ассемблера действительно быстр и занимает мало места, но код, написанный на языке ассемблера, не является кодом многократного использования.Эта функция повторного использования кода является наиболее важной функцией для разработки программного обеспечения.Например, если у вас есть код проекта на ассемблере для процессора x86, его можно использовать только для процессора x86, а не для процессора ARM.Но если у вас есть код project C / C ++ для процессора x86, вы можете использовать этот код для процессора ARM.Таким образом, лучше избегать ассемблера для разработки программного обеспечения.

Очень жаль, что до сих пор никто не упомянул Forth или Scheme.И то, и другое может подойти для небольших помещений и обеспечить впечатляющий прирост производительности.

Обычный C или Pascal, Модуль2.Но из- за доступности компилятора это означает C.

Дополнения к C ++ и им подобным интересны только с точки зрения стиля, поскольку динамическое распределение и размер программы обычно очень ограничены.

Кроме того, более сложная среда выполнения может стать проблемой, если ваши приложения становятся жесткими.

Ассемблер тоже может быть полезен, но только если вы продаете действительно гигантские партии, а меньшая прошивка означает меньший по размеру и более дешевый чип (меньше флэш-памяти), а размер программы поддается контролю (читать:есть некоторый шанс, что вы получите его без ошибок вовремя)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top