AVRASM: Библиотека Подпрограмм общего назначения "GENPROCLIB.INC"

AVR
Библиотека «Подпрограмм общего назначения» содержит самые необходимые процедуры, нужные практически в каждом проекте: для Записи/Чтения памяти EEPROM; для Временной Задержки; и др.


Назначение

Данная библиотека написана на языке ассемблера, для компилятора AVRASM. Соответственно, она предназначена для разработки программных прошивок (firmware) на языке ассемблер, для микроконтроллеров Atmel AVR (8-bit).

Код библиотеки сейчас размещается в одном файле «genproclib.inc» и разделён по функциональным разделам. Внимание: в отличие от кода Макросов, код Подпрограмм — всегда и полностью ВКЛЮЧАЕТСЯ В СЕГМЕНТ КОДА программы — т.е. занимает место! Поэтому код разделён на секции, которые можно отключать директивами условной компиляции — чтобы оставить только те процедуры, которые реально используются:
.EQU	_GENPROCLIB__EEPROM_	= 1	; Процедуры Записи/Чтения памяти EEPROM
.EQU	_GENPROCLIB__DELAY_	= 1	; Процедуры Временной Задержки
.EQU	_GENPROCLIB__RANDOM_	= 1	; Генератор псевдослучайных чисел (ГПСЧ)
.EQU	_GENPROCLIB__TIMER0_	= 1	; Сервисные процедуры для Timer/Counter0

Для улучшения читабельности, код отформатирован в едином стиле (инспирированном «Atmel appnotes» и авторским чувством целесообразности). На каждую подпрограмму имеются комментарии: по Назначению, Параметрам и Побочным Эффектам (какие регистры задействованы, и как изменяются в процессе).

Код процедур — универсален, предназначен для всех микроконтроллеров AVR. (По крайней мере, была предпринята попытка сделать код универсальным. Пишите багрепорты, если что не так.) И вероятно, в будущем, библиотека будет ещё пополняться новыми функциями…

Код

Код библиотеки «genproclib.inc» опубликован на GitHub (это веб-сервис для хостинга IT-проектов и их совместной разработки), на условиях лицензии MIT (разрешительной opensource, т.е. практически без ограничений к использованию). Ответвляйтесь!

Зависимости: Данный код использует (и требует подключения) нестандартную внешнюю библиотеку: «Библиотека базовых Макроопределений (macrobaselib.inc)»… Последнюю версию которой можно скачать на GitHub

Обратите также внимание на «Шаблон нового проекта» — для старта разработки программной прошивки (firmware) на языке ассемблер, в среде «AVR Studio 4», для микроконтроллеров Atmel AVR. Этот код, также, опубликован на GitHub, на условиях лицензии MIT… Вы можете использоваться этот Шаблон для новых проектов прошивок. Код основан на идеях и рекомендациях DI HALT, создан и проверен «в бою»: при работе над реальным проектом. Это чистый шаблон, без прикладного кода. Код Шаблона также содержит единый стиль форматирования, и комментарии с рекомендациями и описанием секций кода...


Примечание: GitHub был выбран для распространения кода — как наиболее прогрессивный, удобный и функциональный метод взаимодействия opensource-разработчиков. Развивайте и дополняйте библиотеку — затем, сможете легко контрибутить...

Ликбез для неискушённых пользователей: те кто не используют системы управления версиями, могут просто скачать архив с кодом: нажав на кнопку «Download ZIP» на странице репозитория GitHub, по ссылкам выше.
  • +4
  • 02 февраля 2014, 14:56
  • Celeron

Комментарии (45)

RSS свернуть / развернуть
Хм… а зачем нужна эта библиотека подпрограмм?
Почему под avrasm? Atmel перестал развивать этот продукт по причине его неконкурентноспособности.
Если так уж хочется на ассемблере писать(зачем?), то можно использовать ассемлер AVRGCC или IAR, соблюдая call conversion и прочие правила использования asm+Си.
Иначе — это путь в никуда, тупик.
парадигму программирования: с хранением «модели прикладных данных» в ОЗУ и использованием нескольких «временных регистров»
Имхо эта парадигма лет на 10-15 отстала. Не нужно её развивать. Уже и АВР отмирают… А вы всё под avrasm парадигмы придумываете…
+2
«Ассемблер уже затем учить следует, что он ум в порядок приводит» (с) М.В.Ломоносов
+1
Ассемблер уже затем учить следует, что он ум в порядок приводит
В этом была трагическая ошибка великого учёного…
0
;-D
0
Проекты полностью на ASM — это для AVR вполне обычное дело. Но библиотеку, кмк, лучше было сделать в виде макросов, тк делать call к функции в несколько инструкций (а таких — много) — не рационально. AVR — и так не очень быстрый процессор.
-1
Аргумент за процедуры: В отличие от макросов, в процедурах можно использовать Ветвления и Циклы (они терпят Метки внутри), их код легче поддерживать. Также, их легче согласовывать с прикладным кодом, организовывать циклы и вложенные вызовы — поскольку интерфейс процедур более упорядочен и код изолирован (меньше побочных эффектов).

лучше было сделать в виде макросов, тк делать call к функции в несколько инструкций — не рационально.
Согласен, там много очень коротких функций — может быть, со временем, решу выделить часть кода в ещё некий <genmacrolib.inc>… На самом деле, эта библиотека родилась между делом, вместив в себя общий код из нескольких проектов. Но её идеология ещё не устоялась.
0
они терпят Метки внутри
avrasm2 спокойно использует метки внутри макросов. Чтобы научить этому avrasm надо писать @Label. Результат тот же.
0
надо писать @Label.

странно. я как-то особо по этому поводу никогда не парился — писАл метки как в обычной основной программе, и всё работало. хотя, может просто не понял, про что сейчас речь.
0
ПисАл по памяти, ошибся. Метка в макросе записывается так $Label.
0
Во, нашел, как раз про это — forum.easyelectronics.ru/viewtopic.php?p=266560#p266560
0
Да, что-то такое есть и работает… Жаль только, что это не документировано. А недокументированное — не стоит использовать.

Официально рекомендуемый синтаксис — относительной адресации от PC (но это забодаешься смещение высчитывать):
RJMP PC-2

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

Проверил: ассемблер AVRASM2 терпит в макросах и метки с префиксом '$' (вероятно для обратной совместимости), и обычные голые метки… Причём, при компиляции, для меток используемых в макросах — смещение генерируется совсем иначе (с суфиксами), чем для регулярных меток! Символ '$' в названиях меток, при этом, игнорируется (пробовал ассемблировать и так и этак — результат одинаковый). Смотрю MAP-файл:
; обычные метки вне макросов
CSEG RESET        0000004f
CSEG MAIN         00000080
CSEG RTOS_METHOD_ProcessTaskQueue 000000f3
CSEG RTOS_METHOD_AddTask 000000d9
; метки внутри макросов
CSEG LoopTimer__RTOS_TIMER_SERVICE@RTOS_TIMER_SERVICE@2878 0000001d
CSEG SkipTimer__RTOS_TIMER_SERVICE@RTOS_TIMER_SERVICE@2878 0000002e
CSEG EndTimer__RTOS_TIMER_SERVICE@RTOS_TIMER_SERVICE@2878 00000032
; пример метки внутри макроса, когда макрос вставлен в код два раза подряд
CSEG LOOP__RAMFLUSH@RAMFLUSH@3071 00000054
CSEG LOOP__RAMFLUSH@RAMFLUSH@3085 0000005c
(Окно Дизассемблера также демонстрирует правильно развязанные адреса в инструкциях Branch/Jump.)

Вывод: в современном AVRASM2 — можно использовать метки, и лучше писать обычные голые Label (без префикса $).
0
Жаль только, что это не документировано.
В хелпе Студии дествительно про $ ничего не сказано. А вот в хелпе А51 — ассемблер для 51 сказано однозначно, PC и $ указатели на текущий адрес. А перед меткой в макросе делает ее локальной.
Вывод я бы сформулировал так, в современном AVRASM2 локализация меток в макросе не обязательна, но и вреда не приносит. Если же возможна компиляция под AVRASM, локализация меток в макросах обязательна.
0
Тогда вопрос: Как правильнее локализовать?
Есть макрос… Префиксы $ следует приписать: и к самой Метке, и при Ссылке на неё?
.MACRO	RAMFLUSH
	LDI	ZL, Low (SRAM_START)
	LDI	ZH, High(SRAM_START)
	CLR	temp

$LOOP__RAMFLUSH:
	ST	Z+, temp
	CPI	ZL, Low (RAMEND+1)
	BRNE	$LOOP__RAMFLUSH
	CPI	ZH, High(RAMEND+1)
	BRNE	$LOOP__RAMFLUSH
.ENDM
0
Кстати, попробовал только что откомпилировать тестовый проект под AVRASM (какой же он всё-таки убогий! пришлось закомментить кучу кода, чтобы съел)

Так вот, немаркированные метки (голый LOOP__RAMFLUSH) — также адекватно обрабатывает. Смотрю MAP-файл:
CSEG ramflush.4.loop__ramflush 0000000d
CSEG ramflush.5.loop__ramflush 00000013


А вот, синтаксис $Label — вообще не переваривает!
$LOOP__RAMFLUSH:  (syntax error)
BRNE	$LOOP__RAMFLUSH  (operand expected)
0
Префиксы $ следует приписать только самим меткам.
Проверял это и в AVRASM, все работало, единственно кроме метки на строке больше ничего не должно быть.
0
У вас длина метки 14 символов. Лень искать, но вроде раньше она была ограничена, кажется 12 символов.
0
Чтобы добить вопрос: Переименовал метку в просто «LOOP»…
Так компилится нормально:
.MACRO	RAMFLUSH
		;...
		LOOP:
		ST	Z+, temp
		CPI	ZH, High(RAMEND+1)
		BRNE	LOOP
		CPI	ZL, Low(RAMEND+1)
		BRNE	LOOP
	.ENDM


А так — нет (макрос использован только раз):
.MACRO	RAMFLUSH
		;...
		$LOOP:
		ST	Z+, temp
		CPI	ZH, High(RAMEND+1)
		BRNE	LOOP
		CPI	ZL, Low(RAMEND+1)
		BRNE	LOOP
	.ENDM

...\test2\project1.asm(53) : error : Syntax error
...\test2\project1.asm(53) : error : Undefined variable referenced
...\test2\project1.asm(53) : error : Undefined variable referenced


Тут дело не в этом. Лучше, всё же, символ $ не использовать с Метками в AVRASM… Что-то вы напутали. Может то был другой компилятор, или AVRASM ранней версии?
p.s. В общем, для себя, я уже прояснил этот вопрос. Так что, эту дискуссию, в принципе, можно не продолжать.
0
Проекты полностью на ASM — это для AVR вполне обычное дело.
Ну не знаю — разве что для тех у которых ОЗУ нет. Для тех на Си не напишешь. Но это совсем мелкота. Да и какие именно вы имеете в виду?
Я из самого мелкого писал для tiny4/5 — и то на Си…
0
Ну не знаю — разве что для тех у которых ОЗУ нет. Для тех на Си не напишешь.
Всё равно умудряются.
0
Можно умудрится, но не нужно — вот для таких случаев асм и существует. Ни для чего больше он не нужен(почти). Только психику им калечить разве что…
0
Да тоже, можно сказать, не актуально. Лет 8-10 назад такие контроллеры ещё в ходу были, а сейчас их использовать чистый мазохизм.
0
чистый мазохизм
Да — это для любителей помучится…
Ну или разве что корпус мелкий — у тины4-5 — 6 -ножка совсем мелкая, но и там на Си писать можно…
0
Тини85 — тоже 6-ножка, но 8 кило флеша, и много памяти (не помню, то ли 256, то ли 512). Да ещё АЦП с предусилитлем. Хоть обпишись! :)
0
Тини85 — тоже 6-ножка
Нет — 8-ми ножка.
Сравните размеры SOIC-8 и SOT23. Разница большая.
0
Тини85 — тоже 6-ножка
Нет — 8-ножка.
SOIC-8 совсем не то что SOT23. Сравните…
0
А, ну да. Но всё равно мелкая :)
0
Только психику им калечить разве что…
Психику асмом покалечить сложно, это один из самых простых языков.
0
Образ мЫшления ломает — перегружает мозг кучей ненужных деталей. Отучает думать о главном — решении задачи.
0
Не ломает, а тренерует!
Да, это распространённое заблуждение для новичков относительно ассемблера. (Я когда-то тоже так думал, не так уж давно...) На самом же деле, ассемблер отличается от Си на столько же, как Си отличается от SQL — совершенно разные парадигмы программирования!
В то время как Си — «алгоритмический язык» (то что вы называете «главным»), но ассемблер является «машинным языком» (в нём другие сущности манипулирования: регистры, порты, инструкции АЛУ). В Си отсутствуют такие понятия, как и средства для манипуляции этими сущностями (Си знает только «переменные») — доступ к аппаратным ресурсам осуществляется через HAL-библиотеки и костыли компилятора…
Например, у «декларативного языка» SQL есть строго ограниченная ниша применения: общие запросы к БД. Причём, в отдельных случаях, функционал Запросов можно расширить пользовательскими агрегатными или скалярными хранимыми процедурами/функциями, написанными на Си. Но равным образом, применяются ассемблерные вставки в Си-код (уродливые костыли) — там, где Си, ну никак, не справляется.
Программировать простые автоматы, с примитивным алгоритмом, на Си — всё равно что ковырять миниатюрную схему толстыми плоскогубцами: не удобно, не эффективно, иногда невозможно. Всякой задаче — свой инструмент.

p.s. Вот ещё: «когда я был молодой», то думал, что языки Java и JavaScript — похожи. Но оказалось — ну, совсем разные вещи: как носорог и дерево (хотя оба — в серой морщинистой коже, казалось бы)…
+1
Программировать простые автоматы, с примитивным алгоритмом, на Си — всё равно что ковырять миниатюрную схему толстыми плоскогубцами: не удобно, не эффективно, иногда невозможно. Всякой задаче — свой инструмент.
Совершенно не согласен. Программировать простые автоматы на асме — всё равно что микроскопом гвозди забивать. Если так делать и проект при этом целиком на асме — даже не знаю с чем сравнить — пц какое-то…
0
в свое время писал проекты полностью на Асме… Скажу вам: Ничего ужасного в этом нет. Если грамотно оформить, то видны и циклы, и условия и «процедуры». Зато эффективность кода на порядок (то бишь в 10 раз) эффективнее. Сейчас потихоньку начинаю лениться, перехожу на си в большинстве своем, но теперь с пониманием всего процесса некоторые вещи уже пишутся с учетом тех знаний, что уже имеются…
0
Если писать на С правильно, то десятикратный прирост эффективности можно получить только в очень редких и специфичных случаях. Лучшие компиляторы уже сейчас генерируют более эффективный код, чем программисты — по крайней мере, на x86.
+1
Да нечему там тренироваться. Предельно простой язык. Сложностей только две — очень большой объем кода для даже простейших задач (а именно объем кода определяет количество ошибок в нем и степень его контролируемости) и неудобен в чтении (write-only). А писать на асме просто, правда и ошибок насажать еще проще.
Хотя знать асм, разумеется, надо — просто для того, чтобы понимать как сам процессор работает.
+2
В то время как Си — «алгоритмический язык» (то что вы называете «главным»), но ассемблер является «машинным языком» (в нём другие сущности манипулирования: регистры, порты, инструкции АЛУ).
Есть говорить о парадигмах, то С — структурно-процедурный, тогда как ассемблер — бесструктурный. Как Бейсик.
в нём другие сущности манипулирования: регистры, порты
Си знает только «переменные»
Вообще-то, это одно и то же. Вот между командами ассемблера (машинными командами) и операторами СС разница есть.
Программировать простые автоматы, с примитивным алгоритмом, на Си — всё равно что ковырять миниатюрную схему толстыми плоскогубцами: не удобно, не эффективно, иногда невозможно.
Чушь. Ассемблер — инструмент для машинно-специфичных задач (таких, как переключение контекстов — в С отсутствует требуемый для этого прямой доступ к регистрам самого процессора, или гипервизоры в системах виртуализации) и тонкой оптимизации. Программировать на нем «простой автомат» — глупо. За исключением тех случаев, когда программирование на ином языке невозможно.
+1
+0x1005000
0
Я сейчас говорю об ассемблере, не как об инструменте, не о средстве. Но говорю, как про мировоззрение: взгляд на программную реальность через призму ассемблера — совершенно другой, чем в алгоритмических языках. Ассемблер здесь — не «язык», а «глаза» и «руки»…
Когда мой Ум входит в мир ассемблера — он начинает функционирует как автомат. Здесь, тренинг ума ассемблером — даёт способность сходить с «ума алгоритмического», в «ум автоматный».

Инструкции ассемблера (машинные команды) — это «руки», которыми микроконтроллер перекладывает кусочки информации (разновидность материи) между имеющимися у него аппаратными регистрами. Как простой автомат: взять оттуда (бит или байт) переложить туда; если здесь пусто («глаза» — условные конструкции) то переложить сюда; и так далее…
У автомата нет алгоритма — вы творец!
0
Взгляд разве что на то, как процессор работает. Нет, зание ассемблера, безусловно, необходимо, но про выворачивание мозгов — это не к нему. И даже не к brainfuck'у, несмотря на его название.

И я бы не назвал ассемблер автоматным языком. Это типичный императивный («алгоритмический») язык, в этом плане он от С не отличается ничем.
+2
Да и код из самого поста — типично императивный. К автоматам отношения не имеет.
+1
Инструкции ассемблера (машинные команды) — это «руки», которыми микроконтроллер перекладывает кусочки информации (разновидность материи) между имеющимися у него аппаратными регистрами. Как простой автомат: взять оттуда (бит или байт) переложить туда; если здесь пусто («глаза» — условные конструкции) то переложить сюда; и так далее…
У автомата нет алгоритма — вы творец!
Какая-то запутанная и идеализирования аналогия.

Конкретный язык (или даже парадигма программирования) — это инструмент. И я выберу тот инструмент, который удобен для меня, а не для микроконтроллера :) Код на ассемблере нереально поддерживать, он не переносим между платформами, он заставляет меня концентрироваться на вещах, которые современный компилятор может решить быстрее и эффективнее.

ИМХО, знать ассемблер полезно (например, иногда это нужно при отладке). Хорошо, когда программист умеет приблизительно прикинуть, как его код, написанный на языке высокого уровня, будет оттранслирован в инструкции процессора. Но я не вижу (в современных реалиях) смысла глубоко изучать ассемблер конкретной платформы или использовать данный ЯП для написания программ.
+1
Язык — это мировоззрение…
0
Язык — это всего лишь инструмент. Хотя разные инструменты диктуют/открывают и разные подходы к решению задачи, но не более.

P.S. А зачем ты отвечаешь сам себе?
0
Хотя разные инструменты диктуют/открывают и разные подходы к решению задачи, но не более.
Я бы сказал так: разные инструменты более или менее удобны для различных подходов. Скажем, на С вполне можно писать в ОО парадигме, но торчащие наружу потроха засоряют код и усложняют написание и сопровождение.
0
Но говорю, как про мировоззрение: взгляд на программную реальность через призму ассемблера — совершенно другой, чем в алгоритмических языках.
Учитывая, что С это, по сути, макроассемблер для PDP, разницы ровно 0.
+1
В Си отсутствуют такие понятия, как и средства для манипуляции этими сущностями
Таки сам язык Си и не должен давать доступ к особенностям контроллера — все контроллеры разные, на всех сей не напасёшься. А добавлять кучу сущностей «на всякий случай» в стандарт как-то неправильно. Хотя локально добавляют, но куда им деваться, если устройство контроллера не совсем вписывается в язык. В новых контроллерах специально архитектуру составляют, чтоб и компилятору было немного удобнее (стм8, арм) =)

Но с помощью библиотек, по крайней мере, в кортексах можно написать программу вовсе без асма, даже с переключениями контекста ОС и прочей ерундой. Эффективность такого решения под вопросом, но принципиально никто не мешает так делать.
0
Ну если на нем и учиться программировать — то, возможно, действительно приведет к таким же последствиям, как Бейсик (о котором Дейкстра говорил «Студентов, ранее изучавших Бейсик, практически невозможно обучить хорошему программированию. Как потенциальные программисты они подверглись необратимой умственной деградации»).
0
Автор топика запретил добавлять комментарии