Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Keil ассемблер, видимость констант (EQU) между модулями

Пт ноя 03, 2023 14:49:08

Привет любителям ARM-ов! Теперь я тоже с вами...
Решил для общего развития поизучать 32-битные контроллеры, взял bluepill с stm32f103 и st-link, "доапгрейдил" свой keil до arm (до этого работал в нем с C51, а с AVR, соответственно в AVR Studio 4).
Почитал интернет, даташиты, обучалки, конечно все в основном на С со всякими библиотеками и прочим, но это все мне не интересно, мне нужен ассемблер, а по нему маловато... Ну не в этом дело.

В общем кое-что покопипастил, кое-что сам понаписал, разогнал ядро до 72МГц, светодиодиком помигал, таймером SysTick ногой с частотой 1кГц подрыгал, стал разбираться дальше и застрял на тупой вещи...
В AVR и 51-х я делал какой-нибудь Define.asm и пихал туда все определения, для которых не было места с отдельных модулях, потом один раз писал include "Define.asm" в главном модуле и все, все модули видят все определения. Тут че-то затык.
Написал в Define.s:
Код:
FLG_1MS_BIT      EQU   0x08 ; какой-нибудь флаг, например что прошла 1 мс
AREA __data, DATA, READWRITE
FLAGS   DCD   0  ; кусок памяти где все флаги собраны
END

В Main.s написал:
Код:
 include   C:\KEIL\ARM\Projects\stm32f10x.asm ;определения регистров и прочего
 include   C:\KEIL\ARM\Projects\MacroSTM.asm
 include   Define.s
 EXPORT   FLAGS ;чтобы было видно в других модулях
 EXPORT   FLG_1MS_BIT
 [...] ;тут всякий код...
LOOP
 LDR   R0,=FLAGS ;проверяем флаг
 LDR   R1,[R0]
 TST   R1,ONE, LSL #FLG_1MS_BIT
 BLNE   EXEC_1MS_TIMER ;если прошла 1мс, переход на обработчик
 B   LOOP
 ENDP
 END

А в модуле, который отвечает за системный таймер такое:
Код:
 include   C:\KEIL\ARM\Projects\stm32f10x.asm
 include   C:\KEIL\ARM\Projects\MacroSTM.asm
 EXTERN   FLAGS
 EXTERN   FLG_1MS_BIT
[...] ;тут всякий код...
ISR_SYSTIMER     PROC ;обработчик прерывания SysTick, раз в 1мс
 PERIH_BIT_CONTROL   SET,GPIOC_ODR,GPIO_ODR_ODR13 ;импульс, чтобы видеть частоту осциллографом
 LDR   R0,=FLAGS ;читаем адрес флагов, тут без проблем
 LDR   R1,[R0] ;загружаем флаги
 BFI   R1,ONE,#FLG_1MS_BIT,#1 ;выставляем нужный бит (ONE=R11=#0x01, определено в макросах)... А ВОТ НИФИГА, не работает!!!
 STR   R1,[R0] ;сохраняем флаги
 PERIH_BIT_CONTROL   CLEAR,GPIOC_ODR,GPIO_ODR_ODR13 ;задний фронт импульса
 BX    LR
 ENDP

И вот строчка с BFI дает "error: A1150E: Bad symbol, not defined or external", на FLAGS не ругается, хотя сделано все одинаково. Че ему не нравится? :dont_know:
Если написать напрямую " BFI R1,ONE,#0х08,#1" или закомментить "EXTERN FLG_1MS_BIT " и вписать его тут же с equ, то все естественно компилится и работает.

PS: чето внутри тега code форматирование не работает...

Re: Keil ассемблер, видимость констант (EQU) между модулями

Пт ноя 03, 2023 16:49:20

конечно все в основном на С
И это не спроста. Не занимайтесь ерундой, тут асм не даёт никаких преимуществ, одни минусы.

Re: Keil ассемблер, видимость констант (EQU) между модулями

Пт ноя 03, 2023 19:47:14

Пол дня читал тут ветку про армы, вот так и знал что кто-нибудь влезет с подобным комментарием. Не надо. Вопрос был конкретный. Не знаете что ответить, не пишите, С не интересует. Мне нравится именно ассемблер. Я однажды переписал tcp/ip стек Lifelover-а для enc28j60 с сайта easyelectronix с С на ассемблер AVR, теперь мега с дачи показывает мне html страничку с температурами в доме, так что я осознаю все + и - обоих языков.

Re: Keil ассемблер, видимость констант (EQU) между модулями

Пт ноя 03, 2023 20:20:15

Engineer_Keen - всё правильно, так и быть должно. Объявления символа FLAGS внешним нужно скорее для линкера, поэтому компилятор его "проглатывает" и оставляет линкеру разбираться с ним, в то время как символ FLG_1MS_BIT нужен компилятору прямо сейчас для замены его на соответствующую константу в коде. Компилятор компилирует файлы исходного кода независимо друг от друга, поэтому не может заменить FLG_1MS_BIT на значение определённое в другом файле.

Правильнее было-бы определить константы созданные EQU в отдельном файле, скажем, constants.inc и инклюдить его во все файлы исходников, где они нужны. Для остальных имён, определённых в составе AREA используйте директиву EXPORT/GLOBAL для объявления имени как глобальное и там где их нужно использовать в других файлах используйте IMPORT/EXTERN. Конкретно, в Define.s уберите 1-ю строчку и добавьте
EXPORT FLAGS
а в файлах Main.s и другом модуле добавьте
INCLUDE constants.inc
IMPORT FLAGS

Re: Keil ассемблер, видимость констант (EQU) между модулями

Пт ноя 03, 2023 21:17:39

Ser60, спасибо, значит буду делать так. Я сначала и инклюдил define в оба модуля, но так как там и equ и ячейка памяти, то с битом в этом случае ошибки не было, но вот ячейка FLAGS задвоилась и стала для каждого модуля своя, что впрочем логично, но я еще удивился, че это компилятор на дубликат не ругнулся :facepalm:

Re: Keil ассемблер, видимость констант (EQU) между модулями

Вс ноя 05, 2023 01:52:22

Константа в ассемблере буквально подменяет написанное, адреса для неё не существует.
Константа в Си заменяет имя переменной для которой уже есть адрес.

Re: Keil ассемблер, видимость констант (EQU) между модулями

Вс ноя 05, 2023 07:37:36

AVI-crak, в общем случае это не так.
Изображение
Screenshot_20231105-073122_Chrome~2.jpg
(59.59 KiB) Скачиваний: 168

Re: Keil ассемблер, видимость констант (EQU) между модулями

Вс ноя 05, 2023 13:20:04

VladislavS - покажи мне, как Си код может увидеть equ определение из асмы. И как асма может увидеть #define константу из Си.
Буду сильно благодарен.

Re: Keil ассемблер, видимость констант (EQU) между модулями

Пн ноя 06, 2023 09:21:54

Сами придумали, сами показывайте. Я тут причём? Мой пример про адрес в памяти.

Re: Keil ассемблер, видимость констант (EQU) между модулями

Пн ноя 13, 2023 19:29:16

И как асма может увидеть #define константу из Си.
В IAR - может. И видит.
Ответить