Версия для печати темы
Форум разработчиков электроники ELECTRONIX.ru _ Keil _ Embedded assembler syntax in C
Автор: MySOL Mar 12 2018, 07:35
Доброго времени суток!
Прошу подсказать или показать пример, как создать в коде на Си участок из ассемблерного кода (пишу критическую секцию и важно быть уверенным во времени исполнения участка). Нужно ли подключать какие-либо библиотеки и проводить дополнительные настройки?
http://electronix.ru/redirect.php?http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/index.html на сайте ARM видел. Я пытался скопировать его. Компилятор понимает директивы, но команды ассемблера не понимает.
Спасибо!
Автор: Baser Mar 12 2018, 11:04
По ссылке на сайте АРМ, там руководство по использованию их ассемблера, это немного не то.
Если вы пишете под Кейлом, то изучайте руководство на Кейл. Напр. у ИАРа все подробно расписано.
А по технологии, применяют или отдельные файлы на ассме, куда помещают функции, написанные согласно соглашениям о вызовах данного компилятора, или ассемблерные вставки прямо в тексте Си.
Все должно быть описано в руководстве на компилятор.
Если куски ассма большие, лучше в файлы, т.к. вставки ассма в Си плохо воспринимают оптимизаторы компиляторов.
Автор: jcxz Mar 12 2018, 11:05
Цитата(MySOL @ Mar 12 2018, 09:35)
Прошу подсказать или показать пример, как создать в коде на Си участок из ассемблерного кода (пишу критическую секцию и важно быть уверенным во времени исполнения участка).
Реализовать участок кода в виде отдельной функции в asm-файле.
Автор: ViKo Mar 12 2018, 11:22
"ARM ® Compiler v5.06 for µVision armcc User Guide" документ с сайта ARM нужно скачать и почитать, там очень много полезного, рекомендую.
Единственный кусок асм-кода, что имею:
Код
__asm void HardFault_Handler(void)
{
B .
BX LR
}
Автор: MySOL Mar 12 2018, 13:18
Господа, спасибо за ответы!
Почитал кейловский мануал и решил написать простую функцию:
Код
__asm void test(int i){
}
Компилятор ругается на "void"
http://electronix.ru/redirect.php?https://postimg.org/image/upkpjj2wj/
Автор: ViKo Mar 12 2018, 13:31
Не обращайте внимания. Это не компилятор, и не на void.
Автор: MySOL Mar 12 2018, 13:39
Цитата(ViKo @ Mar 12 2018, 16:31)
Не обращайте внимания. Это не компилятор, и не на void.
Понял, спасибо! В ближайшее время опробую и отпишусь!
Автор: jcxz Mar 12 2018, 14:24
Если нужно именно в си-код добавить участок асм-кода (а не целиком функцию на асм), то лучше использовать intrinsic-функции. Если они есть в Keil. В IAR для этого их и использую.
Если функция целиком на асм, то лучше написать её в отдельном асм-файле.
Автор: ViKo Mar 12 2018, 14:41
Цитата(jcxz @ Mar 12 2018, 17:24)
Если нужно именно в си-код добавить участок асм-кода (а не целиком функцию на асм), то лучше использовать intrinsic-функции. Если они есть в Keil.
В Кейл есть, естественно. Но это же только замена некоторых уникальных asm-команд. Как они могут заменить "участок асм-кода"?
Автор: jcxz Mar 12 2018, 18:12
Цитата(ViKo @ Mar 12 2018, 16:41)
В Кейл есть, естественно. Но это же только замена некоторых уникальных asm-команд. Как они могут заменить "участок асм-кода"?
Никак. Но и смешивать си-код и асм, не зная какие регистры и как использует первый - чревато.
Вот Вы написали "BX LR", а ведь в LR в конце функции не обязательно будет адрес возврата, если пролог функции "написал" си-компилятор.
Автор: KRS Mar 12 2018, 18:54
Цитата(jcxz @ Mar 12 2018, 21:12)
Но и смешивать си-код и асм, не зная какие регистры и как использует первый - чревато.
Если только не использовать asm в стиле gcc extended asm
gcc и IAR это поддерживают.
Автор: ViKo Mar 13 2018, 04:13
Цитата(jcxz @ Mar 12 2018, 21:12)
Никак. Но и смешивать си-код и асм, не зная какие регистры и как использует первый - чревато.
Вот Вы написали "BX LR", а ведь в LR в конце функции не обязательно будет адрес возврата, если пролог функции "написал" си-компилятор.
Какой пролог? Вся функция показана. Название в том числе.
Умный компилятор Кейла (полагаю, как и другие) считает R0, R1 и т.п. не названиями регистров, а именами переменных.
Да, Кейл, естественно, выполняет соглашение о порядке передачи аргументов в функцию.
Автор: jcxz Mar 13 2018, 12:59
Цитата(ViKo @ Mar 13 2018, 06:13)
Какой пролог? Вся функция показана. Название в том числе.
Если это и есть
вся функция, то нафига её писать в си-файле??? Для этого существуют асм-файлы.
Про пролог сказано для случая смешивания си-кода и асм-кода в одной функции как хочет автор. Читайте внимательнее.
"Пролог" - это набор инструкций, который вставляется компилятором (си) в начало функции. Это может быть PUSH ..., может быть PUSH ...;SUB SP,..., могут быть пересылки аргументов в другие регистры или ещё чего - зависит от содержимого функции. К ассемблеру отношения не имеет.
Автор: ViKo Mar 13 2018, 13:25
Поначалу функцию имел следующую:
Код
__asm void HardFault_Handler(void)
{
TST LR, #4
ITE EQ
MRSEQ R0, MSP ; Main Stack was used, put MSP in R0
MRSNE R0, PSP ; Process Stack was used, put PSP in R0
LDR R0, [R0, #24] ; Get stacked PC from stack
LDR R1, =0x40020418 ; GPIOB->BSRR
MOVS R2, #0x0002 ; Bit 2
STRH R2, [R1, #2] ; Reset bit (LED_ON)
B .
}
Здесь без ассемблера не обойтись. Потом упростил. Не пробовал писать ее на С. Думаю, такой простоты на С не получится.
Автор: jcxz Mar 13 2018, 13:43
Цитата(ViKo @ Mar 13 2018, 15:25)
Поначалу функцию имел следующую:
__asm void HardFault_Handler(void)
Ну - у меня тоже обработчик fault-ов на асм написан. Только он в несколько десятков раз больше.
Защёлкивает содержимое всех важных регистров, кадра стека, разной информации о fault-е и сохраняет в структуру в памяти.
И расположен он в асм-файле. А потом оттуда - переход на си-функцию, которая эту всю инфу уже использует (выплёвывает в UART в аналог "синего окна смерти" или пишет в журнал событий и перегружает МК).
А вот атомарные операции с эксклюзивным доступом я написал на си, с помощью intrinsic-функций, типа (атомарная операция "сравнение и обмен"):
Код
inline u32 AtomicCmpSwp(u32 volatile *ptr, u32 newVal, u32 cmpVal)
{
u32 i, i1;
do {
i = __LDREX(ptr);
if (i == cmpVal) i1 = __STREX(newVal, ptr);
} while (i == cmpVal && i1 == 1);
return i;
}
Аналог виндовой InterlockedCompareExchange()...
PS: Если автору "важно быть уверенным во времени исполнения участка" - нужно для минимизации времени запрета прерываний внутри критической секции, то использование подобных операций эксклюзивного доступа даёт возможность обойтись вообще без запретов прерывания. Если уж так хочется.
Автор: ViKo Mar 13 2018, 14:04
Цитата(jcxz @ Mar 13 2018, 16:43)
Ну - у меня тоже обработчик fault-ов на асм написан. Только он в несколько десятков раз больше.
Есть пример такого обработчика в книгах Джозефа Ю. У меня рабочий макет всегда на столе, подключиться отладчиком в нутро не проблема. Поэтому обошелся тем, что показал.
Автор: jcxz Mar 13 2018, 14:20
Цитата(ViKo @ Mar 13 2018, 16:04)
Есть пример такого обработчика в книгах Джозефа Ю. У меня рабочий макет всегда на столе, подключиться отладчиком в нутро не проблема. Поэтому обошелся тем, что показал.
Я о том, что подозреваю что ТСу вообще "асм в си" не нужен. А хочет он уменьшить время запрета прерываний в критических секциях. А делается это после прочтения мануала по командам LDREX/STREX. Как всегда приходится домысливать неозвученное за автора....
Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)