Jump to content

    

Embedded assembler syntax in C

Доброго времени суток!

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

Пример на сайте ARM видел. Я пытался скопировать его. Компилятор понимает директивы, но команды ассемблера не понимает.

Спасибо!

Share this post


Link to post
Share on other sites

По ссылке на сайте АРМ, там руководство по использованию их ассемблера, это немного не то.

Если вы пишете под Кейлом, то изучайте руководство на Кейл. Напр. у ИАРа все подробно расписано.

 

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

Все должно быть описано в руководстве на компилятор.

 

Если куски ассма большие, лучше в файлы, т.к. вставки ассма в Си плохо воспринимают оптимизаторы компиляторов.

Share this post


Link to post
Share on other sites
Прошу подсказать или показать пример, как создать в коде на Си участок из ассемблерного кода (пишу критическую секцию и важно быть уверенным во времени исполнения участка).

Реализовать участок кода в виде отдельной функции в asm-файле.

Share this post


Link to post
Share on other sites

"ARM ® Compiler v5.06 for µVision armcc User Guide" документ с сайта ARM нужно скачать и почитать, там очень много полезного, рекомендую.

 

Единственный кусок асм-кода, что имею:

 

__asm void HardFault_Handler(void)
{
    B .
    BX LR
}

Share this post


Link to post
Share on other sites

Господа, спасибо за ответы!

 

Почитал кейловский мануал и решил написать простую функцию:

__asm void test(int i){
  
}

 

Компилятор ругается на "void"

 

image.png

 

Share this post


Link to post
Share on other sites

Не обращайте внимания. Это не компилятор, и не на void.

Share this post


Link to post
Share on other sites
Не обращайте внимания. Это не компилятор, и не на void.

Понял, спасибо! В ближайшее время опробую и отпишусь!

Share this post


Link to post
Share on other sites

Если нужно именно в си-код добавить участок асм-кода (а не целиком функцию на асм), то лучше использовать intrinsic-функции. Если они есть в Keil. В IAR для этого их и использую.

Если функция целиком на асм, то лучше написать её в отдельном асм-файле.

Share this post


Link to post
Share on other sites
Если нужно именно в си-код добавить участок асм-кода (а не целиком функцию на асм), то лучше использовать intrinsic-функции. Если они есть в Keil.

В Кейл есть, естественно. Но это же только замена некоторых уникальных asm-команд. Как они могут заменить "участок асм-кода"? :laughing:

Share this post


Link to post
Share on other sites
В Кейл есть, естественно. Но это же только замена некоторых уникальных asm-команд. Как они могут заменить "участок асм-кода"? :laughing:

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

Вот Вы написали "BX LR", а ведь в LR в конце функции не обязательно будет адрес возврата, если пролог функции "написал" си-компилятор.

Share this post


Link to post
Share on other sites
Но и смешивать си-код и асм, не зная какие регистры и как использует первый - чревато.

Если только не использовать asm в стиле gcc extended asm

gcc и IAR это поддерживают.

 

Share this post


Link to post
Share on other sites
Никак. Но и смешивать си-код и асм, не зная какие регистры и как использует первый - чревато.

Вот Вы написали "BX LR", а ведь в LR в конце функции не обязательно будет адрес возврата, если пролог функции "написал" си-компилятор.

Какой пролог? Вся функция показана. Название в том числе.

Умный компилятор Кейла (полагаю, как и другие) считает R0, R1 и т.п. не названиями регистров, а именами переменных.

 

Да, Кейл, естественно, выполняет соглашение о порядке передачи аргументов в функцию.

Share this post


Link to post
Share on other sites
Какой пролог? Вся функция показана. Название в том числе.

Если это и есть вся функция, то нафига её писать в си-файле??? Для этого существуют асм-файлы.

Про пролог сказано для случая смешивания си-кода и асм-кода в одной функции как хочет автор. Читайте внимательнее.

"Пролог" - это набор инструкций, который вставляется компилятором (си) в начало функции. Это может быть PUSH ..., может быть PUSH ...;SUB SP,..., могут быть пересылки аргументов в другие регистры или ещё чего - зависит от содержимого функции. К ассемблеру отношения не имеет.

Share this post


Link to post
Share on other sites

Поначалу функцию имел следующую:

__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 .
}

Здесь без ассемблера не обойтись. Потом упростил. Не пробовал писать ее на С. Думаю, такой простоты на С не получится.

Share this post


Link to post
Share on other sites
Поначалу функцию имел следующую:

__asm void HardFault_Handler(void)

Ну - у меня тоже обработчик fault-ов на асм написан. Только он в несколько десятков раз больше. :biggrin:

Защёлкивает содержимое всех важных регистров, кадра стека, разной информации о 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: Если автору "важно быть уверенным во времени исполнения участка" - нужно для минимизации времени запрета прерываний внутри критической секции, то использование подобных операций эксклюзивного доступа даёт возможность обойтись вообще без запретов прерывания. Если уж так хочется.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this