mysol 0 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба Доброго времени суток! Прошу подсказать или показать пример, как создать в коде на Си участок из ассемблерного кода (пишу критическую секцию и важно быть уверенным во времени исполнения участка). Нужно ли подключать какие-либо библиотеки и проводить дополнительные настройки? Пример на сайте ARM видел. Я пытался скопировать его. Компилятор понимает директивы, но команды ассемблера не понимает. Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 3 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба По ссылке на сайте АРМ, там руководство по использованию их ассемблера, это немного не то. Если вы пишете под Кейлом, то изучайте руководство на Кейл. Напр. у ИАРа все подробно расписано. А по технологии, применяют или отдельные файлы на ассме, куда помещают функции, написанные согласно соглашениям о вызовах данного компилятора, или ассемблерные вставки прямо в тексте Си. Все должно быть описано в руководстве на компилятор. Если куски ассма большие, лучше в файлы, т.к. вставки ассма в Си плохо воспринимают оптимизаторы компиляторов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 181 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба Прошу подсказать или показать пример, как создать в коде на Си участок из ассемблерного кода (пишу критическую секцию и важно быть уверенным во времени исполнения участка). Реализовать участок кода в виде отдельной функции в asm-файле. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба "ARM ® Compiler v5.06 for µVision armcc User Guide" документ с сайта ARM нужно скачать и почитать, там очень много полезного, рекомендую. Единственный кусок асм-кода, что имею: __asm void HardFault_Handler(void) { B . BX LR } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mysol 0 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба Господа, спасибо за ответы! Почитал кейловский мануал и решил написать простую функцию: __asm void test(int i){ } Компилятор ругается на "void" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба Не обращайте внимания. Это не компилятор, и не на void. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mysol 0 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба Не обращайте внимания. Это не компилятор, и не на void. Понял, спасибо! В ближайшее время опробую и отпишусь! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 181 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба Если нужно именно в си-код добавить участок асм-кода (а не целиком функцию на асм), то лучше использовать intrinsic-функции. Если они есть в Keil. В IAR для этого их и использую. Если функция целиком на асм, то лучше написать её в отдельном асм-файле. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба Если нужно именно в си-код добавить участок асм-кода (а не целиком функцию на асм), то лучше использовать intrinsic-функции. Если они есть в Keil. В Кейл есть, естественно. Но это же только замена некоторых уникальных asm-команд. Как они могут заменить "участок асм-кода"? :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 181 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба В Кейл есть, естественно. Но это же только замена некоторых уникальных asm-команд. Как они могут заменить "участок асм-кода"? :laughing: Никак. Но и смешивать си-код и асм, не зная какие регистры и как использует первый - чревато. Вот Вы написали "BX LR", а ведь в LR в конце функции не обязательно будет адрес возврата, если пролог функции "написал" си-компилятор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 12 марта, 2018 Опубликовано 12 марта, 2018 · Жалоба Но и смешивать си-код и асм, не зная какие регистры и как использует первый - чревато. Если только не использовать asm в стиле gcc extended asm gcc и IAR это поддерживают. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 марта, 2018 Опубликовано 13 марта, 2018 · Жалоба Никак. Но и смешивать си-код и асм, не зная какие регистры и как использует первый - чревато. Вот Вы написали "BX LR", а ведь в LR в конце функции не обязательно будет адрес возврата, если пролог функции "написал" си-компилятор. Какой пролог? Вся функция показана. Название в том числе. Умный компилятор Кейла (полагаю, как и другие) считает R0, R1 и т.п. не названиями регистров, а именами переменных. Да, Кейл, естественно, выполняет соглашение о порядке передачи аргументов в функцию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 181 13 марта, 2018 Опубликовано 13 марта, 2018 · Жалоба Какой пролог? Вся функция показана. Название в том числе. Если это и есть вся функция, то нафига её писать в си-файле??? Для этого существуют асм-файлы. Про пролог сказано для случая смешивания си-кода и асм-кода в одной функции как хочет автор. Читайте внимательнее. "Пролог" - это набор инструкций, который вставляется компилятором (си) в начало функции. Это может быть PUSH ..., может быть PUSH ...;SUB SP,..., могут быть пересылки аргументов в другие регистры или ещё чего - зависит от содержимого функции. К ассемблеру отношения не имеет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 марта, 2018 Опубликовано 13 марта, 2018 · Жалоба Поначалу функцию имел следующую: __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 181 13 марта, 2018 Опубликовано 13 марта, 2018 · Жалоба Поначалу функцию имел следующую: __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: Если автору "важно быть уверенным во времени исполнения участка" - нужно для минимизации времени запрета прерываний внутри критической секции, то использование подобных операций эксклюзивного доступа даёт возможность обойтись вообще без запретов прерывания. Если уж так хочется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться