Jump to content

    
mysol

Embedded assembler syntax in C

Recommended Posts

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

Есть пример такого обработчика в книгах Джозефа Ю. У меня рабочий макет всегда на столе, подключиться отладчиком в нутро не проблема. Поэтому обошелся тем, что показал.

Share this post


Link to post
Share on other sites
Есть пример такого обработчика в книгах Джозефа Ю. У меня рабочий макет всегда на столе, подключиться отладчиком в нутро не проблема. Поэтому обошелся тем, что показал.

Я о том, что подозреваю что ТСу вообще "асм в си" не нужен. А хочет он уменьшить время запрета прерываний в критических секциях. А делается это после прочтения мануала по командам LDREX/STREX. Как всегда приходится домысливать неозвученное за автора.... :laughing:

Share this post


Link to post
Share on other sites

Подниму тему.

 

Keil, compiler v6.12 (armclang).

Есть модуль, состоящий из 3 файлов: .s, .c и .h.

В .c-файле глобально объявлена структура

struct _dev
{
  u32          a;
  volatile u32 b;
  volatile u32 c[MAX_C_QNT];
  u32         *d[MAX_D_QNT];
}Dev;

 

В .h-файле, помимо объявления прототипов функций, макрос-функций и т.д., есть макроопределения MAX_C_QNT и MAX_D_QNT.

 

В .s-файле реализована функция, которая работает со структурой выше.

Все бы ничего, но... как обратиться к элементу 'd'? Параметр 'c' имеет вариативный размер.

 

Существуют ли адекватные способы в Keil рассчитать смещение от начала структуры до нужного элемента в .s-файле?

В .s-файл можно включить .h-файл с макроопределениями MAX_C_QNT/MAX_D_QNT, но в этом .h ничего, кроме как этих определений, тогда быть не должно.

А плодить заголовочные файлы как-то не хочется.

 

P.S. Пока что на ум приходит использовать синтаксис встроенного ассемблера в .c-файле. Но, ИМХО, не комильфо. Я считаю, что asm-коду место в .s-файлах...

Share this post


Link to post
Share on other sites
28 минут назад, Arlleex сказал:

Параметр 'c' имеет вариативный размер.

Почему? Насколько я понял, MAX_C_QNT - это константа?

А, понял. Проблема во включении *.h-файла в *.S? Вот это не поможет?

Share this post


Link to post
Share on other sites
14 минут назад, AHTOXA сказал:

Почему? Насколько я понял, MAX_C_QNT - это константа?

#define обычный.

#define MAX_C_QNT 5, допустим.

 

Смысл в том, что в Си-коде любые смещения будут высчитываться автоматически.

А ведь ассемблерному надо знать эти же MAX_C_QNT и т.д.

 

Грубо говоря, из ассемблерной функции надо обратиться к 0-му элементу параметра 'd' структуры Dev.

Собственно, пишу

     PRESERVE8
     THUMB
     AREA |.text|, CODE, READONLY
     
func PROC
     EXPORT func
     IMPORT Dev
     
     push {r1-r4}
     
     ldr  r1, =Dev      ; берем адрес Dev
     ldr  r2, [r1]      ; получаем значение 'a'
     ldr  r3, [r1, ???] ; западло: как достучаться до 'd', не зная, сколько элементов в 'c'?
     ...

 

То есть в .s-файле должно быть видно определение MAX_C_QNT.

 

14 минут назад, AHTOXA сказал:

А, понял. Проблема во включении *.h-файла в *.S? Вот это не поможет?

О. Сейчас почитаю:smile:

Share this post


Link to post
Share on other sites

.S вместо .s не помогло.

Во вкладке 'Asm' в Keil-е в Misc Controls вписал -E -x assembler-with-cpp eds.s.

Теперь мне компилятор ругается так

Спойлер
Цитата

Rebuild started: Project: CANTrainBus
*** Using Compiler 'V6.12', folder: 'D:\Program Files\Keil\ARM\ARMCLANG\Bin'
Rebuild target 'sources'
assembling eds.s...
eds.s: Error: A1067E: Output file specified as 'eds.s', but it has already been specified as '.\objects\eds_1.o'
eds.s: Error: A1067E: Output file specified as 'user\eds.s', but it has already been specified as '.\objects\eds_1.o'
compiling hw.c...
compiling main.c...
compiling eds.c...
compiling stm32f10x_crc.c...
compiling stm32f10x_adc.c...
compiling stm32f10x_gpio.c...
compiling stm32f10x_can.c...
assembling startup.s...
startup.s: Error: A1067E: Output file specified as 'eds.s', but it has already been specified as '.\objects\startup.o'
startup.s: Error: A1067E: Output file specified as 'system\startup.s', but it has already been specified as '.\objects\startup.o'
compiling stm32f10x_iwdg.c...
compiling stm32f10x_i2c.c...
compiling stm32f10x_spi.c...
compiling stm32f10x_rcc.c...
compiling stm32f10x_usart.c...
compiling stm32f10x_tim.c...
".\Objects\CANTrainBus.axf" - 4 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed:  00:00:01

 

:wacko2:

 

26 минут назад, _pv сказал:

добавить

const sizе_t max_c_cnt = MAX_C_QNT;

чтобы из ассемблера его видно было.

Это я понимаю. Но я не хотел плодить, по сути, одинаковые константы.

Share this post


Link to post
Share on other sites

ну препроцессор можно отдельно на что угодно натравить gcc -E < input > output

и тогда добавить в ассемблерный файл #define MAX_C_CNT или #include "header.h" если там ничего кроме примитивных дефайнов констант нету.

он и в ассемблерном файле точно так же заменит  MAX_C_CNT на 5.

 

Share this post


Link to post
Share on other sites
27 минут назад, _pv сказал:

если там ничего кроме примитивных дефайнов констант нету.

Именно. У меня .h-ник не только препроцессорные директивы содержит =(

Ладно. Сейчас сделал ход конем - поменял порядок элементов в структуре, чтобы гарантированно знать положение 'd'.

Решение такое себе, конечно (в плане дальнейшего применения в других задачах). Но конкретно тут оно смотрится вполне адекватно.

Share this post


Link to post
Share on other sites
4 часа назад, Arlleex сказал:

Во вкладке 'Asm' в Keil-е в Misc Controls вписал -E -x assembler-with-cpp eds.s. 

Теперь мне компилятор ругается так

-E, на мой взгляд, лишнее.

2 часа назад, Arlleex сказал:

Именно. У меня .h-ник не только препроцессорные директивы содержит =(

Если это свой *.h, то его можно разделить на два. Или вставить проверку (это для GCC, не знаю, так ли для шланга)

#ifndef __ASSEMBLER__

// здесь то, что не должен видеть ассемблер

#endif

 

Share this post


Link to post
Share on other sites
19 минут назад, AHTOXA сказал:

-E, на мой взгляд, лишнее.

Без него тоже было не густо...

Щас вообще сижу переписываю стартап-файл для своего МК.

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

Share this post


Link to post
Share on other sites
3 минуты назад, Arlleex сказал:

Без него тоже было не густо...

А, и "eds.s" тоже лишнее. Это же ключи, а имя файла подставит сам кейл.

4 минуты назад, Arlleex сказал:

На строчку .if Heap_Size != 0 ругается

Если научитесь передавать опцию -x assembler-with-cpp, то можно будет писать привычно:

#if Heap_Size != 0

5 минут назад, Arlleex сказал:

Охренительный инструмент, блин... Пора уходить на IAR, видимо:wacko:

Это же gcc-шный синтаксис, его есть смысл изучить. Тем более, что и IAR уже тоже движется в этом направлении. По крайней мере, inline assembler для него уже полностью повторяет GCC-шный (пример).

Share this post


Link to post
Share on other sites
2 минуты назад, AHTOXA сказал:

А, и "eds.s" тоже лишнее. Это же ключи, а имя файла подставит сам кейл.

Ага. Попробовал.

В принципе для этих целей в Keil-е есть галочка на вкладке 'Asm'.

Она этот ключик сама добавляет в список ключей командной строки.

 

Я, если честно, не совсем понимаю структуру документации, какие мне документы нужны для полноты картины.

Вот, нашел вот такой документ. С ним более-менее понятно, какие директивы на какие поменялись при миграции компилятора.

Но откуда выцыганить внятное описание самих директив? Их синтаксис, возможные вариации и т.д?

 

Типичный пример: читая документ выше, вижу, что функции в ассемблере оформляются как .type Reset_Handler, "function".

Открываю в дебрях установленного Keil-а шаблонный стартап для моего ядра и вижу .type Reset_Handler, %function.

Вот сижу и думаю: я об этой разнице в % и "" сам должен догадаться (есть она или ее нету) или оно где-то описано? =)

Share this post


Link to post
Share on other sites
4 минуты назад, Arlleex сказал:

Но откуда выцыганить внятное описание самих директив? Их синтаксис, возможные вариации и т.д?

Здесь я, к сожалению, не помощник, потому что не использую кейл :-)

Share this post


Link to post
Share on other sites
2 минуты назад, AHTOXA сказал:

Здесь я, к сожалению, не помощник, потому что не использую кейл :-)

А, коли не секрет, чем пользуетесь? Просто интересно =)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.