Панегирик по AVR

Греки заимствовали у египтян обычай говорить речи при погребении усопших и создали впоследствии из этого обычая особый род литературы и ораторского искусства. Уже во времена Солона такого рода речи при общественных похоронах произносились не кем-нибудь случайно, а известным лицом, по назначению. «De mortuis aut bene, aut nihil» («О мёртвых или хорошо, или ничего»), говорили римляне, и надгробные речи их всегда отличались похвалами, причём первоначальная искренность уступала место риторике, по мере того, как речи эти приобретали официальный характер и стали служить предлогом для похвалы живым.

https://ru.wikipedia.org/wiki/Панегирик

Но AVR, к сожалению, ещё не помер. Поэтому про него будет сказано и хорошее, и плохое. Сказано искренне, как это и полагается у древних греков.

Причиной написания этого панегирика явилось хорошо знакомое всем чувство, которое выражается кратной, но ёмкой фразой, — «Достало уже!!!»

Взяться снова за решение проблем, связанных с AVR, меня заставило мое чувство долга и ответственности перед теми, кого я подсадил на AVR и Linux. Нехорошо кидать своих «протеже».

В общем, вчера ко мне обратился один товарищ (ФИО, ИНН и другие реквизиты не называю по понятным причинам) со следующей проблемой. Он не может отассебмлировать свой проект для микроконтроллера AVR в Линуксе.

По факту, я в свое время тоже не смог это осилить. Но я нахожусь несколько впереди, поэтому наверно могу чем-то помочь. Наверно. Я тоже так думал — наверно могу. Оказалось, не могу.

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

.nolist
;.include "/usr/share/avra/m1284Pdef.inc"
.include "m1284Pdef.inc"
.list 
                     
.section .text
.org 0
jmp  initial


.org 0x46
initial:
ldi        r16, RAMEND & 0x00ff
out        SPL, r16
ldi        r16, RAMEND >> 8
out        SPH, r16
ldi        XH, 0x11
jmp        initial

Товарищ пытается этот исходник отассемблировать следующей командой

$ avr-as -als=lighting.lst -warn -mmcu=atmega1284P -o lighting.o lighting.asm

Единственная придирка к большой букве «P» в типе микроконтроллера. Там должна быть маленькая. Но это так, придирка. Глобальная проблема же в том, что текст не хочет ассемблироваться. Файл m1284Pdef.inc тоже имеется в наличии, и лежит по правильному адресу.

Ассемблер не может переварить названия регистров SPH и SPL. Ну есть и другие проблемы, до которых я таки не дошёл.

Ассемблер avr-as — это какое-то голое дитя. В его комплекте нет ассемблерных inc-файлов, где описаны регистры, биты регистров и так далее. Хедерные файлы от Си-компилятора, понятно, — не подходят, ибо имеют совершенно иную организацию и правила написания.

Очередное погружение в Интернет показало, что линуксовый народ ассемблирование для AVR не озабочен. От слова «совсем». А если и встречаются отдельные одиозные личности, то они в своих проектах делают ассемблерные вставки, но чистых ассемблерных проектов под Линуксом для AVR — нет.

Однако, гугление натолкнуло меня на мысль, что для AVR-тулчейна более правильно будет ассемблировать не в ассемблере (блин, сюрреализм какой-то!), а из-под avr-gcc.

Далее привожу мой ответ (с небольшими изменениями) товарищу.

Я посидел ночку с проблемой… и ничего путного не добился.

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

Исходник в приложении к письму.

; blink.S
; Тупая демо-программа ничего полезного не делает, только блымкает светодиодами

#define __SFR_OFFSET 0

#include <avr/sfr_defs.h>
#include <avr/io.h>

#define T100MS          (100)
#define T10000US        (1000)

#define tmpreg  R16     // Регистр для временного хранения
#define counter R4      // Счетчик

.section .text
.org 0
.global start
        rjmp    start
        
;===============================================================================
        .org 0x46
start:
        ; Инициализируем стек
        ldi	tmpreg, lo8(RAMEND)
        out	SPL, tmpreg
        ldi	tmpreg, hi8(RAMEND)
        out	SPH, tmpreg
        
        ; Настраиваем порты
        rcall   initports
        rcall   initwatchdog
        
        clr     tmpreg        
        mov     counter, tmpreg
mainloop:
        wdr
        mov     tmpreg, counter
        com     tmpreg
        out     PORTB, tmpreg
        rcall   delay_100ms
        
        inc     counter
        rjmp	mainloop        ; крутимся в бесконечном цикле

;===============================================================================
delay_100ms:
        ldi     XL, lo8(T100MS)
        ldi     XH, hi8(T100MS)
delay_100ms_loop:
        rcall   delay_1ms
        sbiw    XL, 1
        brne    delay_100ms_loop
        ret
        
;===============================================================================
delay_1ms:
        ldi     YL, lo8(T1000US)
        ldi     YH, hi8(T1000US)
delay_1ms_loop:
        sbiw    YL, 1
        brne    delay_1ms_loop
        ret

;===============================================================================
; Инициализация портов
initports:
        ser     tmpreg
        out     DDRB, tmpreg
        out     PORTB, tmpreg
        ret
        
;===============================================================================
; Инициализация собаки
initwatcdog:
        ldi     tmpreg, 0x1F
        out     TIMSK0, tmpreg  // Здесь должен быть не TIMSK0, а WDTCSR
        ldi     tmpreg, 0x0F
        out     DDRC, tmpreg    // То же самое. Но даже с TIMSK0 не работает!
        ret

dalay:
        

.end

По идее прога должна светодиодами «перебирать» двоичный код, а собака должна прерывать этот набор где-нибудь на полпути. То есть счетчик не должен доходить до максимума и обнуляться. На код не обращайте внимания, там наверняка полно логических ошибок. Я программу не отлаживал. Программа вообще не может отассемблироваться!

На что я хотел бы обратить Ваше внимание.

1. Я пошел по другому пути. Я не стал использовать ассемблер напрямую, то есть вызывать avr-asm. Я решил отдавать исходник на «съедение» avr-gcc.

avr-gcc — это не совсем компилятор с языка Си. Это, скорее, оболочка, которая вызывает либо компилятор, либо линковщик, либо тот же ассемблер. Делает это он всё в зависимости от ситуации и передаваемых ему ключей.

Для ассемблирования ему нужно отдать исходник на ассемблере.

А поскольку он сам хорошо разбирается в инклюд-файлах, то иметь каких-то специальных инклюдов для ассемблирования не надо. avr-gcc будет с удовольствием пользоваться си-шными инклюдами для ассемблирования.

Но часть правил по конвертированию исходников в двоичный код находятся жестко в внутри avr-gcc (лежат в модуле). То есть ему не нужны никакие внешние файлы с именами процессорных команд или регистров.

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

Так вот, так или иначе, для ассемблирования в каких-то случаях можно использовать avr-gcc. Я попробовал. К сожалению, не удачно. Намеченного результата — получение двоичного кода программы — достичь не удалось.

Но тем не менее, поскольку что-то работает и даже что-то получается, то, вот, — делюсь полученными знаниями.

2. В исходном файле перед вызовом инклюда:

#include <avr/io.h>

нужно прописать определение:

#define __SFR_OFFSET 0

Собственно, указывать конкретный инклюд для заданного в проекте микроконтроллера не надо. avr-gcc сам определяет этот инклюд на основании параметра -mmcu=. Единственное, что необходимо сделать — это в исходном файле указать инклюд io.h, который находится в поддиректории avr.

Но дело в том, что часть определений запрятана внутри avr-gcc. И для правильной работы с инклюдом ему (avr-gcc) нужно дать подсказку в виде строки #define __SFR_OFFSET 0.

Этот хакерский «фокус» я нашел где-то в англо-язычном интернете, а потом увидел его описание в инклюд-файле, который входит в состав тулчейна. Этот файл — sfr_defs.h. У меня он лежит в директории

/usr/lib/avr/include/avr

Но в этом же файле сказано, что это есть грязный хак (hack). И на сколько я понял по контексту его описания, то это не совсем то, что следует рекомендовать простым людям. Не, его там (в этом файле), конечно, рекомендуют использовать, но мне как доктору несколько стрёмно давать в руки граждан такие средства как скальпель, этиловый спирт или обезболивающие наркотические вещества. Люди — разные. Люди могут начать применять эти средства не по по их прямому назначению. На ком будет висеть ответственность за последствия?

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

	out	SPL, R16

начали нормально транслироваться в код.

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

	out	WDTCSR, R16

Я сломался. Я сдался. Я в очередной раз понял, что архитектура AVR — это что-то! Ну её нахрен! Это пройденный этап в развитии микроконтроллеров. Отработала она своё. Скажем ей огромное спасибо и отправим в сундук на пенсию.

Если Вам интересно почему я сдался, то скажу, что я понял, что ни о какой унификации в отношении архитектуры AVR говорить не приходится. Если компиляция/ассемблирование проходит для MEGA8, то это ничего не значит в отношении MEGA128.

Например, все регистры периферийных устройств у MEGA8 укладываются в пространство от 0x20 до 0x5F. То для MEGA128 за этим пространством имеется еще одно — от 0x60 до 0x1FF.

Казалось — эти под-пространства входят в одно адресное пространство и особых проблем быть не должно! Как бы не так! Это два разных подпространства, и к ним по разному осуществляется доступ.

К первому подпространству применяется модификаторы __SFR_IO8 или __SFR_IO16, а ко второму — __SFR_MEM8 и __SFR_MEM16.

А появится еще какой-нибудь мутант типа X-Mega, и этот зоопарк еще больше вырастет. Вопрос — нахрена изучать все эти немасштабируемые способы работы?

А по большому счету, вы когда-нибудь видели архитектуру MSP430?

По моему, это классический образец реально очень красивого решения.

Это эталон, на который нужно ровняться. Если вы считаете, что вашим проектам «тесно» 16-разрядной архитектуре, то есть такая же красива 32-разрядная архитектура. Я говорю о Cortex-ах.

Давайте признаемся честно, что в свое время мы «подсели» на AVR не из-за её красоты (ха, каламбур какой!), а из-за демпинговых цен на фоне дрогих и еще более неуклюжих PIC-ов. Из-за легкости программирования через проcтецкие LPT-программаторы.

MSP430 отпугнул людей отсутствием документации по нему, дороговизной средств отладки и программирования. Отсутствием корпусов с большим шагом выводов. Не надо сбрасывать со счетов и необычное по тем временам питание — +3.3В. В те времена радиолюбительский мир в основном юзал 5-вольтовые решения. Грубо говоря — было легче купить микросхему стабилизатора на 5 В, чем на 3.3В.

Поэтому люди массово садились на недорогие AVR-решения.

В заключение хочу еще раз напомнить, что архитектура AVR — это не архитектура, которая легко ложится на язык Си. Язык Си разрабатывался для Фон-Неймановской архитектуры, у которой единое адресное пространство и для программного кода и для данных.

AVR — это типичный представитель Гарвардской архитектуры. У него три с половиной адресных пространства. И они друг с другом никак не пересекаются.

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

Собственно, второе адресное пространство — это область оперативной памяти. Это область для хранения данных. Из этой области нельзя выполнять код.

Третье адресное пространство — это EEPROM. Это память тоже предназначена для хранения данных. Для долговременного хранения данных. Но отсюда так же нельзя полноценно работать с данными. Можно только считывать и записывать. Программный код отсюда тоже нельзя выполнять.

Четвертое адресное пространство — это ото область фьюзов. Да-да! Это тоже адресное пространство для хранения — конкретно — для хранения конфигурации микроконтроллера.

Вроде бы всех развели по разным углам, рассадили на свои законные стульчики и вроде бы никто никого не должен обижать. Данные уже не залезут в программный код и не сломают его. (Ура, вирусы нам не страшны!), а коды команд нельзя вот так взять просто и вынести за пределы проходной, чтобы тиражировать пиратские копии девайса. (Ура, нашу разработку не украдут!)

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

Всё это, конечно, хорошо. Но вот далее начинаются проблемы. За всё нужно плати.

Первый чек пришел на оплату адресного пространства данных. Теперь, все константы (это такие бестии, которые по определению никогда в своей жизни не меняются) нужно копировать из неизменной флэшь-памяти в оперативную. То есть константы перестают быть константами. То есть это мы их считаем константами и нам в голову не приходит изменить у них значение. Но мир, богатый на разнообразия, может «родить» какую-нибудь хрень (типа ошибка в программе или неопытный пользователь), которые просто не знают, что константы по определению нельзя изменять. Но по факту — можно. Он ведь находятся в оперативной памяти. Что мешает? Ни-че-го. И если есть такая возможность упасть — оно обязательно упадёт.

В общем получается так, что все наши константы превращаются в переменные, которые мы, «между нами — девочками», договорились никогда-никогда не менять. Но приходит мальчишка и ломает наш мир. Хреново. Можно начинать плакать.

Следующий чек на оплату. Наши константы, хоть и подвержены изменению, но, допустим, мы контролируем этот процесс. Но что нам делать, когда в нашей программе констант много и они большие? Ну, допустим, у нас девайс имеет LCD-экранчик, на который мы выводим меню. Пункты меню по жизни не меняются. То есть названия пунктов меню — это константные строки.

Для пущей важности я подкину еще дровишек — путь у нас не просто текстовый LCD, а графический. Значит перед нами стоит задача по растеризации символов. Если для отображения буквы «A» в текстовый LCD
достаточно отправить только ее ASCII-код, то в отношении графического LCD мы сами должны позаботится о её по-пиксельном описании.

Прикиньте, какой объем памяти занимает растровая таблица символов? А ведь это таблица — ничто иное как таблица констант. Для буквы «B» комбинация пиксел должна быть только такая и никакая другая. Иначе это будет не буква «B», а буква «D» или цифра «8».

Чтобы работать с таблицей растреризации символов нужно иметь ее в оперативной памяти. Но таблица находится в программной памяти. А где ж ей ещё быть! Ведь при выключении питания все данные в оперативной памяти разрушаются.

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

Что-что там говорили про красивые архитектурные решения?

Так вот, теперь наша крошечная оперативная память забита константами. Не порядок! Оперативы и без того мал, так мы её ещё и транжирим почём зря!

Мы что нибудь можем сделать, чтобы не расходовать понапрасну оперативную память?

Ответ — можем!

Что мы можем сделать? Мы можем не размещать в оперативной памяти константы на всё время работы программы, а «выдергивать» их из программной памяти (и размещать в оперативной) на какое-то короткое время — только тогда, когда они нам нужны для работы. То есть оперативная память не занята, а когда нм понадобится та или иная константа мы ее перенесли из флешь-памяти в оперативную, поработали и снова освободили оперативную память для размещения других данных.

Вроде красивое решение.

Однако. Что-что там говорили про быстродействие архитектуры? Теперь наша программа тем и занимается, что вынимает из флешь-памяти константы. Всё потенциальное быстродействие архитектуры мы потратили на извлечение констант. Опять укусили себя за жопу. Кого хотели обмануть? А кого обманули?

Что касается рабочей лошадки, на которой в основном-то и пишут программы для микроконтроллеров — языка программирования Си, то он изначально не был предназначен для «обслуживания» Гарвардской архитектуры. Стандартный Си не понимает что такое адресное пространство программ и адресное пространство данных. У Си — единое адресное пространство.

Чтобы Си для AVR-архитектуры мог работать с данными, которые размещены по адресу 0x100, и с программным кодом, который тоже размещен по такому же адресу 0x100, но в другом адресном пространстве, были придуманы разные костыли. Костыли они и в Африке — костыли! И вот, получается, что вместо того, чтобы легко и свободно писать свои программы, AVR-программисты занимаются прикручиванием костылей. Пытаются заставить «инвалида» играть в футбол и участвовать в соревнованиях по легкой атлетике наравне с неограниченными в способностях конкурентами.

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

Так может не стоит ставить на кремниевых «инвалидов» изначально?

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

Реклама

22 responses to “Панегирик по AVR

  1. Работаю с Ubuntu. С ассемблером на AVR возился в 2009 году, особых проблем не возникло. Недавно пришлось опять за него взяться, я про AVR, решил не возвращаться и поставил XP в виртуальную машину, а уж туда AVR Studio 4 и один известный отладчик. Сделал проект на ATtiny13, места мало, пришлось жёстко оптимизировать код. Проблему с копированием констант решил через стандартный модуль avr/pgmspace.h. В общем, вспомнил юность и решил задачу реализации таймера на ЖКИ, не опускаясь до ассемблера и узнав много нового об AVR. Но больше такой опыт повторять не хочу, всё-таки на привычных мне STM32 всё проще и логичнее.

    • Ага. Помниться в 2004-06 гг тоже писал для АВР на ассемблере. Только тогда я сидел в Шиндовсе… А когда пересел на Линукс, то все мои АВР-проекты были Си-шными. Поэтому проблем не возникало.

      Первый раз проблема ассемблирования для АВР из-под Линукса возникла полтора года назад, когда я возился с Tiny13. Но я тогда её не победил. И второй раз — вот сейчас.

      Да, вобщем-то, уже и не надо решать эту проблему. Не актуально. Если нужно выполнить ту же задачу, то дешевле и быстрее её выполнить на базе STM32F0x.

      Эпоха АВР стремительно уходит. Конечно, всегда были и всегда будут те, кто сильно привязан к этой архитектуре. До сих пор ведь 51-ое ядро кем-то востребовано! В отношении АВР ситуация ведь ни чем не отличается.

      Но для себя я решил, что мир АВР, как мир Шиндовс — это было хорошо, весело. Но нужно иметь силы отказаться от этого. Когда-то ведь надо оставлять соски, подгузники, Шиндовсы, АВР-ы.

      Рост, взросление — это нормальный процесс. И в том, что что-то приходится оставлять в детском мире, в этом нет ничего трагичного. Другое дело, что не нет желания расти, учиться, совершенствоваться. Но это уж индивидуально. Каждый сам за себя решает, что ему делать.

  2. Avra никогда не подводила.

    • Да, хорошая была машинка для ногодрыжества. Простая, быстрая и не дорогая.

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

      А кроме того для STM32 даже и программатор не нужен как таковой. Загрузчик уже прописан внутри в ПЗУ и мониторит UART, а у более навороченных USB- и CAN-интерфейсы. То есть достаточно присоединить USB-разъем к лапкам STM32F103x и ты уже можешь заливать в него свой код.

      Да чего там говорить! Тот хотя бы разок основательно покатался, того уже ни на какие другие ядра не впечатляют.

      А АВР — да, оно хорошее решение. Было. Так было лет пять-10 назад. Пока кортексов не было. Но за эти 5-10 лет время мир МК существенно изменился. Никто не виноват, что кто-то из разработчиков не захотел меняться и решил остаться на старых технологиях. Это только его личные проблемы. (Я не имею в виду Вас. Я говорю вообще.)

      Река жизни течет, никого не ждет, никого не спрашивает.

      • Артём

        >>Относительно АВР они чуть сложнее внутри
        Ну последние АВР (xmega) не такие уж и простые — наворотов хватает.

        >>а стоят они даже дешевле соизмеримых по нафаршированности АВР-ок
        Не факт, что дешевле: как-то искали замену xmega256 из STM32, в итоге не нашли. xmega по цене оказалась вполне выгодна.

        >>А кроме того для STM32 даже и программатор не нужен как таковой
        сомнительный плюс — программатор (и отладчик) всё равно нужен, да и стоит копейки

      • >> Ну последние АВР (xmega) не такие уж и простые — наворотов хватает.
        Для меня они закрыты. В Линуксе нет средств для работы с ними, так что пусть ХМеги и их производитель идут лесом, а потерянных потенциальных клиентов, таких как я, пусть привлекают к себе снижением цен на фоне вялого спроса. Как ни крути, при отсутствии лояльности к потребителю и неистовом желании поиметь с клиента денег, веточка (направление) обречена засыхать, какой бы красивой ни была архитектура ядра. (Пример AVR32, пример XMega.)

        Артём, а Вы не заметили, что рынок XMega и рынок STM32 даже несоизмеримы друг с другом? Как вы думаете, почему это так?

        >> как-то искали замену xmega256 из STM32, в итоге не нашли. xmega по цене оказалась вполне выгодна.

        Даже не буду оспаривать. Вам виднее, что Вам больше подходит.

        >> программатор (и отладчик) всё равно нужен, да и стоит копейки

        — сомнительный плюс. Это я про принципиальную необходимость иметь отладчик.

        Про программатор, я думаю, вообще можно не поднимать вопрос. Программатор для STM32 как таковой не нужен! Если в качестве программатора достаточно «пяти проводков» (как в AVR-семействе), то зачем ради только заливки программы покупать программатор?

        А что касается отладчика, то ведь … смотрите — если ваш проект не сильно навороченный, то для отладки достаточно нескольких светодиодов и осциллографа. А осциллограф по нынешним временам есть у каждого серьезного разработчика. А если ваш проект достаточно большой, то в нем наверняка присутствует либо LCD, либо UART, либо какой-нибудь другой интерфейс во внешний мир. Достаточно вписать в сомнительные места отлаживаемой программу вывод ключевых данных, и вы уже будете знать, где «пробегает» выполнение вашей проги и знать значения ваших переменных.

        Да, согласен, чтобы локализовать баг, придётся несколько раз переписать, откомпилировать и залить прогу в МК. Но разве это проблема?

        При неимении отладчика вполне можно отладить практически любую прогу. Не совсем эффективно — это, да. Но это не есть принципиально не возможно. Я не приветствую бедность, но бедность удивительно изобретательна, когда есть желание достичь результата. А когда желания нет, то и наличие отладчика не поможет.

        К стати, отладчик для STM32 стоит в пределах 250-300 рублей. Но даже если и этих денег нет, то можно собрать его самостоятельно. Так о чём речь?

        А к стати! Артём, скажите, сколько стоит отладчик для XМега?

  3. >>Но чуть стоит проекту начать расширяться, тут же возникают непреодолимые проблемы.
    Вы преувеличиваете — в больших проектах и дела нет где какой регистр лежит. Программа пишется на Сях так же как и под Cortex.
    >>Первое адресное пространство — это память программ.
    Это очень маленькое неудобство, можно вполне с этим жить…
    >>Он ведь находятся в оперативной памяти. Что мешает? Ни-че-го. И если есть такая возможность упасть — оно обязательно упадёт.
    А что Cortex не читает константы в регистры? Читает…И как-то программа не падает от этого.

    • Ах, Артём, Артём!
      Вы действительно хотите подискутировать или так себе? Если да, то я отвечу Вам чуть позже. Если нет, то оставим Ваши реплики в воздухе.

      • Артём

        >>Вы действительно хотите подискутировать
        Можно и подискутировать, если хотите.

    • А чёб двум уважаемым мужчинам вечерочком не поговорить за жизнь?.

      Попробую ответить на Ваши доводы.

      1.
      >> в больших проектах и дела нет где какой регистр лежит.
      >> Программа пишется на Сях так же как и под Cortex.

      В моей практике несколько раз были случаи, когда проект разрастался и мне приходилось переходить на другой — более мощную версию МК. В основном это было как раз с применением AVR-ок. Ну, просто до недавнего времени я их и использовал в своих коммерческих и почти-коммерческих проектах. С STM32 я работал еще не очень много, мне до сих пор как-то не посчастливилось упереться в возможности выбранного под проекты микроконтроллеров.

      Помню были случаи, когда нужно было перейти с Tiny2313 на Mega8. Не скажу, что пришлось попотеть, но над изменениями в программе всё-таки пришлось потрудиться. Не буду уточнять какие конкретно регистры и биты у них не совпадает, но то, что пришлось весь проект заново вычитывать (то есть перепроверять имена регисторв периферийных устройств и назначение битов) — это далеко не нулевые трудозатраты на перенос ПО с одной архитектуры на такую же.

      Били переносы проектов с Mega48 на Mega88. Потом на Mega168. Это прошло достаточно легко. Но вот перенос проекта с Mega8 на Mega88 заставил призадуматься.

      А когда пришлось переносить проект с Mega162 на Mega128 я понял, что везде все по разному.

      Хотите примеры? Начнем с регистра MCUCR. У одних МК он называется MCUCR. У других — МCUCSR. У третьих — биты управления спящим режимом вынесены вообще в регистр SMCR.

      Пройдитесь по битам разрешения внешних прерываний. Куда их только не пихали! У Mega162 бит прерывания PCIE0 расположен в регистре GICR. У Mega165 — в EIMSK. У Mega168 — в PCICR.

      Та же чехарда происходит с регистрами таймеров. Нет постоянства. Не-е, конечно, есть определенные группы микроконтроллеров типа Mega48, Mega88, Mega168, Mega328 внутри которых переход от одного к другому осуществляется почти без болезненно. Но давате себя спросим — а как часто бывает переход на более старшую модель связанный с необходимостью увеличения только памяти? Бывает, не спорю. Но чаще случаются апгрейды, когда нужно добавить еще один последовательный порт или добавить ног для подключения LCD.

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

      2.
      >>>> Первое адресное пространство — это память программ.
      >> Это очень маленькое неудобство, можно вполне с этим жить…

      Ну живут же люди с одним глазом, с одной ногой. Да, это несколько неудобно. Но жить можно. Есть даже определённые преимущества.
      Можно из булки хлеба сделать… Но зачем!? Почему нужно хранить какую-то надуманную «верность» этой архитектуре?

      3.
      >> А что Cortex не читает константы в регистры? Читает…И как-то программа не падает от этого.

      Вы, видимо, не понимаете. Попробую объяснить. Наберитесь терпения.

      Чтобы работать с константой, он должна находится в области той памяти, которая является памятью данных. Относительно АВР, константы лежат во флешь-памяти, которая не является памятью данных. Поэтому константы тем или иным способом должны быть перенесены в область оперативной памяти, то есть в память данных. Только тогда можно говорить, что программа (написанная на языке Си) с ними может работать.

      Если вы не работаете с константами через PROGMEM-модуль, то перенос ваших констант будет осуществлён за вас (модулем crt0) еще до вызова функции main. С одной стороны — ничего делать не нужно, всё за вас сделает компилятор с линковщиком. Но с другой стороны, вы лишаетесь какой-то части оперативной памяти. Ладно если в вашей программе пара-тройка констант типа int8_t. Потери памяти будут незаметны. А вот если вы используете LCD, на который вы выводите какие-то константные сообщения для пользователя, то вполне может случиться нехватка памяти.

      А если вы сам «командуете парадом» (то есть используете функции типа pgm_read_byte и pgm_read_word), то вам придется каждый раз терять время на извлечение этих констант из флешь-памяти и размещение их в оперативной памяти. Это тоже сходит с рук, когда константы небольшие, их не так много и система безразлично относится к снижению быстродействия. Но когда у вас цветной графический экранчик (320х240 пиксел), да еще и само устройство — система реального времени, вот тут-то и начинаются танцы с известными ударными инструментами.

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

      А теперь давайте посмотрим как обстоят в отношении Кортексов.

      Архитектура Кортексов хоть и считается Гарвардской, но на самом деле у них единое адресное пространство, как у машин Фон-Неймановского класса. Гарвардский класс определяется по наличию независимых шин доступа для данных и для команд. Но у Кортексов даже не две шины. У Кортесов — матрица аж из шести шин, которые позволяют параллелить операции пересылки данных и команд. Что называется — почувствуйте силу архитектуры! А поскольку единое адресное пространство имеет составляет 4МБ, то дробить его на отдельные никак не связанные друг с другом области — не имеет смысла.

      Грубо говоря, у STM32 если обращение идет в область флешь-памяти (0x0800000…) за получением кода команды, то задействована одна шина. Если идет обращение к этой же области но для считывания данных — то другая шина. Третья шина «работает», когда идет обмен в оперативной памятью. Эти шины работают параллельно и независимо друг от друга. Никто не ждет кем-то занятого ресурса.

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

      Кроме того, единое адресное пространство — это родная аппаратная среда для Си. Не надо придумывать нестандартные для языка средства работы. Не надо ни каких костылей. Все натурально и естественно.

      У меня на моей практике было несколько проектов, которые вырастали от небольшой букашки-ногодрыгалки до систем передачи данных с кнопками и графическим экраном. И я на своей шкуре прочувствовал все прелести этого апгрейдного роста. Один раз был даже уникальный случай — система росла от Mega162 до STM32F103C8, через Mega64 -> Мега128 и STM32F100RB.

      Так вот переход между STM32F100 и F103 оказался менее болезненным, чем переход от Mega162 на Mega64. Почему так, да потому, что у меня кривые руки. А может быть потому, что различий между STM32F100 и F103 по факту оказалось меньше, чем между Mega162 и Mega64.

      Мне неважно, что Вы думаете конкретно по этому случаю. Мне важно, что я увидел сам. Личный опыт — он более значимый, чем всякие интернет-рассуждения.

      Спасибо, что дочитали до конца.

      • «В моей практике несколько раз были случаи, когда проект разрастался и мне приходилось переходить на другой — более мощную версию МК»

        Возникает закономерный вопрос: почему бы сразу не заложить более мощный по объемам памяти кристалл? Скажем, 2-кратный запас – это вообще копейки.

        А еще, у AVR до сих пор есть такое немаловажное преимущество, как выпуск кристаллов в DIP-упаковке.

      • 1. Да хрен его знает, товарищ майор! (с)
        Всегда ведь хочется решить задачу минимальными затратами. А на будущее — как знать — разовьётся проект или нет. У меня достаточно много проектов (разработок) остановились в развитии. Из опубликованных здесь, например, — Эмулятор Каротажных Сигналов. На сегодня, ну у какой смысл его нафаршировывать функциональностью? Не нужно это сегодня. А завтра? — А вот хрен его знает! Может для него вместо Mega168 нужно было сразу брать Cortex-M4. Или что, это уже перебор для этого проекта? Мне Бог подсказок не присылает.

        А двукратный запас — ну как вариант, может быть и можно рассматривать. Но вопрос — а двукратный запас по какому параметру? По оперативе? По Флэши? По количеству UART-ов? По тактовой частоте? По количеству ног? Да, всё это демагогия!

        — Я думаю 640 килобайт памяти должно хватать на все случаи жизни (с) Билл Гейтс

        А сколько сейчас оперативы в новом средне-статистическом компе? 8, 16 Гигов или больше? Миллиардер не смог угадать, что ж Вы, уважаемый, от меня-то хотите!

        2. Да, этот печальный факт, к сожалению, имеет место быть. Но, к счастью, у ST появились корпуса с более крупным шагом выводов — TQFP с шагом 0.8 мм. Что касается меня лично (в прочем, и многих других разработчиков), то начальное макетирование я произвожу с использованием оценочных плат. Например, http://www.ebay.com/itm/291302763331?rmvSB=true — ориентировочная цена за штуку $5 USD или 260 рублей по курсу.

        Так что я не вижу какой-то особой западни, которую невозможно решить разумными затратами, с отсутствием у STM32 DIP-ов.

      • Артём

        >> Начнем с регистра MCUCR
        Да, так и есть — развели зоопарк. Такое впечатление что разные отделы проектировали разные семейства АВР.

        >>Почему нужно хранить какую-то надуманную «верность» этой архитектуре
        Ну, если архитектура с задачами справляется, то зачем время тратить на изучение новой архитектуры, даже если она и лучше старой.

        >>константы тем или иным способом должны быть перенесены в область оперативной памяти, то есть в память данных
        Не всегда так — пробовал конструкцию такого вида:
        class Test_t {
        const uint16_t MyConst=1000;
        };
        При работе с MyConst компилятор(IAR) её в ОЗУ не переносил, а вставлял в код (исползовалось сравнение переменных с MyConst).
        Co строками-массивами конечно хуже, без pgm_read_byte не обойтись — немного неудобно, согласен. Хотя в AVRGCC появилась поддержка работы с flash константами без pgm_read_byte.

      • >> Ну, если архитектура с задачами справляется, то зачем время тратить на изучение новой архитектуры, даже если она и лучше старой.

        А я что, против? Полно разработчиков, которых даже сегодня устраивает 51-е ядро. Это ведь их проблемы — изучать новые технологии или продолжать и дальше жевать гавно мамонта. Только вот, меня на 51-е уже не заманишь никакими плюшками! И, думаю, что после нескольких лет работы с Кортексами, я буду то же самое говорить и про AVR. Но это не значит, что Вам нужно идти моей дорогой. Это мой путь, и я никого за собой не зову. А вдруг я ошибаюсь? Так что, уважаемые, кто читает мой блог, идите своей дорогой.

        >> Не всегда так — пробовал конструкцию такого вида: …

        Ну, как бы, всегда можно придумать обходные пути. Можно из булки хлеба сделать троллейбус…

        Но зачем, когда есть нормальная архитектура? Другое дело, вопрос — а что мешает создавать перспективные разработки на этой архитектуре? Только личные предубеждения.

        Ну, не нравится мне ни Шиндовс, ни куча ворованного софта для работы с тем же XMega. Поэтому я их слил куда-следует и смыл, дернув за шнурок. На отлично изучить и использовать все архитектуры микроконтроллеров не имеет никакого смысла. Смысл имеет выбрать то, что тебе — лично тебе, больше подходит. Мне лично больше подходит STM32, и совсем не подходит XMega. Кому-то наоборот. А то-то вообще сделал ставку на AVR32 и сейчас пребывает в состоянии «ел уху».

  4. «Так что я не вижу какой-то особой западни, которую невозможно решить разумными затратами, с отсутствием у STM32 DIP-ов.»

    Обновление фирвари у удаленных заказчиков в девайсах без USB.

    • До сегодняшнего дня эта проблема меня как-то обходила. А что будет завтра — я не знаю. Появятся _конкретные_ задачи, буду придумывать _конкретные_ решения. А так — какой смысл заранее «запасаться гречкой», может лучше сахару закупить?

      • Артём

        >>В Линуксе нет средств для работы с ними, так что пусть ХМеги и их производитель идут лесом
        Toolchain для Linux есть. AtmelStudio может быть можно запустить под WINE. И всё бесплатно.

        >>Артём, а Вы не заметили, что рынок XMega и рынок STM32 даже несоизмеримы друг с другом? Как вы думаете, почему это так?
        Интересно было бы узнать сколько получает ST от STM32 и Atmel от AVR. Но таких данных нет — остаётся только гадать.

        >>Как вы думаете, почему это так?
        ST Micro больше Atmel-а в несколько раз просто.

        >>А что касается отладчика, то ведь … смотрите — если ваш проект не сильно навороченный, то для отладки достаточно нескольких светодиодов и осциллографа.
        Ну, как вы говорите — «Можно из булки хлеба сделать троллейбус…»
        Как раз тот случай.

        >>А осциллограф по нынешним временам есть у каждого серьезного разработчика.
        Ну, раз нашлись деньги на осциллограф, то и на отладчик найдётся — они стоят как правило в несколько раз дешевле.

        >> Достаточно вписать в сомнительные места отлаживаемой программу вывод ключевых данных, и вы уже будете знать, где «пробегает» выполнение вашей проги и знать значения ваших переменных.
        Можно. Но как-то привычней с отладчиком работать. У меня как правило отладка была всегда (кроме того времени когда я работал с AT89).
        Под Scenix,AVR, Cortex, C166 покупалась нужная отладка.

        >>Да, согласен, чтобы локализовать баг, придётся несколько раз переписать, откомпилировать и залить прогу в МК. Но разве это проблема?
        Долго это — один мой проект (на atmega128) отлаживал зашивая через бутлоадер по УАРТу. Каждая зашивка около 5 минут. Запуск через JTAG — секунд 30.

        >>А к стати! Артём, скажите, сколько стоит отладчик для XМега?
        Разные есть — от ~50 $ до 200$. Копейки.
        Программатор покупали год назад за 1300 рублей. Тоже не деньги.

      • >> Toolchain для Linux есть.

        А мы точно говорим про тулчейн для XMega под Linux? А то я года три-четыре назад даже писал в ATMEL, просил их об этом. Но они так ничего и не ответили.

        >> AtmelStudio может быть можно запустить под WINE.

        Ай! Да не люблю я натягивать глобус на сову.

        >> Как раз тот случай.

        Не согласен принципиально! Поговорка про троллейбус применяется тогда, когда человеку хочется что-то сделать, но ума хватает только вот на такой извращение. Использование светодиодов для отладки программы на фоне отсутствия отладчика — это не извращение. Это всего лишь способ жить. Осуждать это — кощунство!

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

        В прочем, это чисто индивидуальный подход к отладке. Кому-то нравится вводить команды в строке, а кто-то привык хлопать мышкой по менюшкам и кнопочкам.

        Вам нравится делать так? Вот и отлично! Делайте так и не спрашивайте меня.

        >> один мой проект
        ключевые слова:
        ОДИН
        МОЙ

        Другие Ваши проекты, а так же проекты других людей — мне кажется их значительно больше, чем ОДИН ВАШ проект. Ну, хорошо-хорошо! — Чем ДЕСЯТЬ ВАШИХ мега-проектов, которые имеют код в несколько десятков килобайт.

        А для одного мега-проекта, я так думаю, смета его стоимости вполне может включить JTAG-отладчик, и никто это даже не заметит. Так что был бы мега-проект, а покупка отладчика не заставит себя долго ждать. А с другой стороны — а нахрена мега-проект делать на AVR-ке, если умеешь обращаться с STM32?

        1300 — за программатор не дорого. За эти деньги можно купить аж 5 штук STLink-2 для STM32. Иметь резерв — это грамотно.

        50-200 баксов за программатор, отсутствие тулчейна под Линукс — это то, что заставляет меня не кидаться в объятия XMeg-и. Ведь стоимость вхождения в лагерь STM32 значительно ниже. Так что мешает? Мешает религия. А кроме того, сейчас мне мешает совершить кульбит на XMeg-у уже полученные знания и опыт использования STM32.

        Если мне уже хорошо с этой женщиной, то зачем мне еще одна?

        То же самое относится и к Вам. Если Вы считаете, что XMega Вас полностью удовлетворяет, то и оставайтесь с ней! Я ведь не Вас приглашаю в клуб любителей STM32.

      • Артём

        >>Ну, не нравится мне ни Шиндовс, ни куча ворованного софта для работы с тем же XMega.
        Почему сразу ворованного? Windows шёл в комплекте к ноуту, Atmel Studio с AVRGCC и ARMGCC — бесплатно.

      • Да потому, что по статистике — кого ни возьми, у всех разработчиков установлен ворованный ПиКад и «крякнутый» IAR или KEIL. Редко кто юзает кастрированные ознакомительные версии. И совсем редко кто покупает эти продукты. Говорю, основываясь только на личном опыте.
        Поэтому, мне нравится мне Шиндовс — он разрушает карму.

  5. >>А мы точно говорим про тулчейн для XMega под Linux.
    Ссылка: http://www.atmel.com/tools/ATMELAVRTOOLCHAINFORLINUX.aspx
    Какого-то отдельного тулчайна для XMEGA не требуется — ядро практически такое же (измененился только режим доступа к регистровому файлу — он теперь не отображён на SRAM, других изменений не вспоминается). Для поддержки xmega добавились параметры:
    —mcu=atxmega192a3u
    вместо
    —mcu=atmega128
    Так что собирать проект можно из командной строки, а зашивать какой-нибудь дудкой.

    >>Ай! Да не люблю я натягивать глобус на сову.
    Да, неблагодарное это занятие.

    >>Использование светодиодов для отладки программы на фоне отсутствия отладчика — это не извращение.
    ИМХО, если постоянно пишешь программы под МК, отсутствие отладчика — это странно.

    >>А кроме того, светодиоды неплохо рулят в системах реального времени. То есть там, где пошагово проходить прогу или ставить точки останова ничего не даст.
    Не всегда можно отладить программу пошагам, согласен. Бывают случаи, когда нельзя останавливать программу. Тогда светодиод самое то.

    >>А с другой стороны — а нахрена мега-проект делать на AVR-ке, если умеешь обращаться с STM32?
    XMEGA AVR — гораздо проще в освоении, если раньше с мегой работал.

    >>За эти деньги можно купить аж 5 штук STLink-2 для STM32.
    Сейчас уже 5 не купишь — рубль упал.
    А как отлаживать STM32 в Linux? В Eclipse?

    >>Ведь стоимость вхождения в лагерь STM32 значительно ниже. Так что мешает?
    Не соглашусь, AVR проще. Не надо всё с нуля переделывать.

    >>Да потому, что по статистике — кого ни возьми, у всех разработчиков установлен ворованный ПиКад и «крякнутый» IAR или KEIL.
    Да, наверное так, хотя сейчас GCC очень к ним приблизился по качеству и почти нет смысла использовать платный софт.

    >> И совсем редко кто покупает эти продукты. Говорю, основываясь только на личном опыте.
    Ну так дорого же…

    >> Поэтому, мне нравится мне Шиндовс — он разрушает карму.
    Сам Windows ни в чём не виноват, карму разрушает использование ворованного ПО, хотя часто бесплатных альтернатив хватает.

    • По XMega.

      Только-что консультировл одного человека, который начинает АВР-ить. Выполнил команду avr-gcc —target-help и увидел присутствие в списках поддерживаемых архитектур XMega. Ну, что — Хорошо! Но поздно. Поезд уже ушёл. Я уехал на поезде STM32. Не возвращаться же!

      >> ИМХО, если постоянно пишешь программы под МК, отсутствие отладчика — это странно.

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

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s