Написание прошивки: сборка или высокий уровень? - PullRequest
19 голосов
/ 17 января 2009

Относится к:

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

Спасибо

Ответы [ 17 ]

32 голосов
/ 17 января 2009

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

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

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

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

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

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

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

Я искал компилятор C ++ для PIC Microchip; единственная найденная мной компания - 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, мы обычно делаем число битов явным. Затем скомпилируйте его и отредактируйте сборку, которую он создает (просто оставьте части кода начала / выхода) и будьте осторожны , чтобы не загромождать любые регистры, не восстанавливая их после того, как вы это сделали.

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

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

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

21 голосов
/ 17 января 2009

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

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

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

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

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

7 голосов
/ 17 января 2009

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

7 голосов
/ 14 февраля 2009

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

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

5 голосов
/ 17 января 2009

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

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

Еще одна вещь, которая конкретно связана с PIC18. Вам не придется иметь дело с неинтуитивной архитектурой PIC и такими вещами, как БАНКИ памяти.

5 голосов
/ 17 января 2009

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

4 голосов
/ 21 января 2009

Перейти на C!

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

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

4 голосов
/ 17 января 2009

В прошлом у меня был хороший опыт работы с IAR C компиляторами.

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

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

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

3 голосов
/ 17 января 2009

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

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

2 голосов
/ 13 февраля 2009

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

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

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

...