реклама на сайте
подробности

 
 
6 страниц V  « < 4 5 6  
Reply to this topicStart new topic
> STM32F0 Время реакции и выполнения прерывания
Влад Р.
сообщение Jun 27 2016, 12:05
Сообщение #76


Частый гость
**

Группа: Свой
Сообщений: 87
Регистрация: 9-12-10
Пользователь №: 61 511



Цитата(jcxz @ Jun 27 2016, 07:57) *
Обычно чтобы символьные имена из асм-файла были видимы в других исходных файлах (си и асм), нужно это символьное имя объявить в директиве PUBLIC.
Ну и, естественно, прописать прототип в си-хидере.
И наоборот: чтобы в асм-файле были видимы имена из других объектных файлов, нужно их указать в директиве EXTERN.
EXPORT я не использую нигде.

Тут случай особый. Это функция-обработчик прерывания. И её прототип указывается в ASM-файле начальной инициализации, который трогать нежелательно. Поэтому в определении функции необходимо директива EXPORT или её синоним GLOBAL.

Цитата(jcxz @ Jun 27 2016, 07:57) *
Можно это квитирование прерывания просто поставить в начале ISR, сразу после входа. Я так и делаю обычно.

В моей ситуации необходимо как можно быстрее после входа в обработчик считать регистр порта в/в. Но в любом случае, это лишнее. Сброс флага внешнего прерывания нормально отрабатывает и непосредственно перед выходом из обработчика.

Написал обработчик на ASMе. Время входа в прерывание удалось сократить до 500 нс. Этого пока достаточно. Как сделать табличные переходы не соображу. Вот, что получилось:
CODE
EXTI_BASE EQU 0x40010400
GPIOA_BASE EQU 0x48000000
GPIOB_BASE EQU 0x48000400
GPIOC_BASE EQU 0x48000800

EXTI_PR_OFFSET EQU 0x14
GPIO_IDR_OFFSET EQU 0x10
GPIO_BSRR_OFFSET EQU 0x18
GPIO_BRR_OFFSET EQU 0x28

MACRO
asmexti_exit
LDR r0, =EXTI_BASE ; загрузить в регистр r0 адрес модуля EXTI
MOVS r1, #0x01 ; загрузить в регистр r1 значение 0x01
LSLS r1, #8 ; логический сдвиг влево на 8 бит значения в регистре r1
STR r1, [r0, #EXTI_PR_OFFSET] ; сохранить слово из регистра r1 в регистр EXTI->PR
BX lr ; возврат из функции
ALIGN
MEND

AREA ASMEXTI, CODE, READONLY
EXTI4_15_IRQHandler PROC
EXPORT EXTI4_15_IRQHandler
LDR r0, =GPIOC_BASE ; загрузить в регистр r0 адрес порта GPIOC
LDRH r0, [r0, #GPIO_IDR_OFFSET] ; загрузить в регистр r0 полуслово из регистра GPIOC->IDR
LSRS r1, r0, #9 ; логический сдвиг вправо на 9 бит значения в регистре r0 и сохранение результата в регистр r1
MOVS r2, #0x0B ; загрузить в регистр r2 значение 0x0B
ANDS r1, r2 ; побитовое И регистра r1 с регистром r2
CMP r1, #0x02 ; сравнить вычитанием из регистра r1 значения 0x02
BEQ C ; условный переход на метку C, если результат операции нулевой
CMP r1, #0x00 ; сравнить вычитанием из регистра r1 значения 0x00
BEQ A ; условный переход на метку A, если результат операции нулевой
CMP r1, #0x01 ; сравнить вычитанием из регистра r1 значения 0x01
BEQ B ; условный переход на метку B, если результат операции нулевой
asmexti_exit
A
MOVS r1, #0xFF ; загрузить в регистр r1 значение 0xFF
ANDS r0, r1 ; побитовое И регистра r0 с регистром r1
LSLS r1, #16 ; логический сдвиг влево на 16 бит значения в регистре r1
ORRS r0, r1 ; побитовое ИЛИ регистра r0 с регистром r1
LDR r2, =GPIOA_BASE ; загрузить в регистр r2 адрес порта GPIOA
STR r0, [r2, #GPIO_BSRR_OFFSET] ; сохранить слово из регистра r0 в регистр GPIOA->BSRR
asmexti_exit
B
MOVS r1, #0x60 ; загрузить в регистр r1 значение 0x60
ANDS r0, r1 ; побитовое И регистра r0 с регистром r1
LSLS r1, #16 ; логический сдвиг влево на 16 бит значения в регистре r1
ORRS r0, r1 ; побитовое ИЛИ регистра r0 с регистром r1
LDR r2, =GPIOB_BASE ; загрузить в регистр r2 адрес порта GPIOB
STR r0, [r2, #GPIO_BSRR_OFFSET] ; сохранить слово из регистра r0 в регистр GPIOB->BSRR
asmexti_exit
C
MOVS r1, #0x0F ; загрузить в регистр r1 значение 0x0F
LSLS r2, r1, #4 ; логический сдвиг влево на 4 бита значения в регистре r1 и сохранение результата в регистр r2
ANDS r2, r0 ; побитовое И регистра r2 с регистром r0
LSLS r2, #4 ; логический сдвиг влево на 4 бита значения в регистре r2
LSLS r3, r1, #24 ; логический сдвиг влево на 24 бита значения в регистре r0 и сохранение результата в регистр r3
ORRS r2, r3 ; побитовое ИЛИ регистра r2 с регистром r3
LDR r3, =GPIOA_BASE ; загрузить в регистр r2 адрес порта GPIOA
STR r2, [r3, #GPIO_BSRR_OFFSET] ; сохранить слово из регистра r2 в регистр GPIOA->BSRR
ANDS r0, r1 ; побитовое И регистра r0 с регистром r1
LSLS r0, #8 ; логический сдвиг влево на 8 бит значения в регистре r0
LSLS r2, r1, #24 ; логический сдвиг влево на 24 бита значения в регистре r0 и сохранение результата в регистр r3
ORRS r0, r2 ; побитовое ИЛИ регистра r0 с регистром r2
LDR r1, =GPIOB_BASE ; загрузить в регистр r1 адрес порта GPIOB
STR r0, [r1, #GPIO_BSRR_OFFSET] ; сохранить слово из регистра r0 в регистр GPIOB->BSRR
asmexti_exit
ENDP
END
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 27 2016, 12:51
Сообщение #77


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Влад Р. @ Jun 27 2016, 15:05) *
Сброс флага внешнего прерывания нормально отрабатывает и непосредственно перед выходом из обработчика.
Инженеры ARM с вами не согласны, поэтому придумали инструкции барьеров (DSB, DMB, IMB). Но вы можете лично наступить на грабли.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Влад Р.
сообщение Jun 27 2016, 13:12
Сообщение #78


Частый гость
**

Группа: Свой
Сообщений: 87
Регистрация: 9-12-10
Пользователь №: 61 511



Цитата(Сергей Борщ @ Jun 27 2016, 15:51) *
Инженеры ARM с вами не согласны, поэтому придумали инструкции барьеров (DSB, DMB, IMB). Но вы можете лично наступить на грабли.

Буду иметь в виду, перенесу сброс флага ближе к началу обработчика. Однако в функции EXTI_ClearITPendingBit() из STM32F0xx SPL этих инструкций нет. И доках от ST об этом тоже ничего.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 27 2016, 14:03
Сообщение #79


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Влад Р. @ Jun 27 2016, 18:05) *
Тут случай особый. Это функция-обработчик прерывания. И её прототип указывается в ASM-файле начальной инициализации, который трогать нежелательно. Поэтому в определении функции необходимо директива EXPORT или её синоним GLOBAL.

Не понял в чём именно проблема. Не обязательно ISR впихивать в файл начальной инициализации, можно создать отдельный файл.
Но впрочем - Ваше дело.

Цитата(Влад Р. @ Jun 27 2016, 18:05) *
Как сделать табличные переходы не соображу.

А что там соображать?
Код
;исходно в R0 - номер ветки ветвления
;допустим - на каждую ветку кода достаточно 32 байт
  LSLS   R0, #5
  ADR    R1, table00
  ADDS  PC, R1, R0

table00: ;ветка для значения 0
  ...
  BX LR
  NOP;добиваем NOP-ами до 32 байт
table01: ;ветка для значения 1
  ...
  BX LR
  NOP;добиваем NOP-ами до 32 байт
table02: ;ветка для значения 2
...

Не уверен что все использованные команды допустимы я ядре M0 (не имею с ним опыта), то думаю - можно заменить на эквиваленты.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 27 2016, 14:12
Сообщение #80


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Код
CMP R0, #3; Compare input to maximum valid choice
BHI default_case; Branch to default case if higher than 3
MOVS R2, #4; Multiply branch table offset by 4
MULS R0, R2, R0; (size of each entry)
LDR R1,=BranchTable; Get base address of branch table
LDR R2,[R1,R0]; Get the actual branch destination
BX R2; Branch to destination
ALIGN 4; Alignment control. The table has
; to be word aligned to prevent unaligned read
BranchTable; table of each destination addresses
DCD Dest0
DCD Dest1
DCD Dest2
DCD Dest3
default_case
.; Instructions for default case
Dest0
.; Instructions for case ‘ 0 ’
Dest1
.; Instructions for case ‘ 1 ’
Dest2
.; Instructions for case ‘ 2 ’
Dest3
.; Instructions for case ‘ 3 ’

Из все той же книги. Пора бы, наконец, за ум взяться!
P.S. scifi-ю читать не надо, там на китайско-английском ржака. lol.gif
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 27 2016, 15:22
Сообщение #81


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 27 2016, 20:12) *
MULS R0, R2, R0; (size of each entry)
...

Однако такой вариант будет даже тормознее switch/case. laughing.gif
Go to the top of the page
 
+Quote Post
Влад Р.
сообщение Jun 27 2016, 15:27
Сообщение #82


Частый гость
**

Группа: Свой
Сообщений: 87
Регистрация: 9-12-10
Пользователь №: 61 511



Цитата(jcxz @ Jun 27 2016, 17:03) *
Не понял в чём именно проблема. Не обязательно ISR впихивать в файл начальной инициализации, можно создать отдельный файл.
Но впрочем - Ваше дело.

На сколько я понял PUBLIC - это аналог EXPORT и GLOBAL, но из других компиляторов. Потому как в Keil его нет. Чтобы показать линковщику откуда брать код, нужно либо прототип функции указать с директивой EXTERN, либо определение функции с директивой GLOBAL. Так? Startup-файл с прототипом функции-обработчика прерывания я трогать не хочу. Вот и указываю определение с директивой EXPORT (она же GLOBAL). Обработчик сейчас и так в отдельном файле.

С табличными переходами логика понятна. Спасибо!
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 27 2016, 15:41
Сообщение #83


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(jcxz @ Jun 27 2016, 18:22) *
Однако такой вариант будет даже тормознее switch/case. laughing.gif

Какого switch/case? Сишного? Таким же и будет. rolleyes.gif
А, ну да, для команд умножения количество тактов написано 1 or 32, Depends on multiplier implementation, в этом документе. http://infocenter.arm.com/help/index.jsp?t...c/CHDCICDF.html
Видимо, Джозеф Ю скопипастил из предыдущей книжки.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 27 2016, 15:59
Сообщение #84


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Влад Р. @ Jun 27 2016, 21:27) *
На сколько я понял PUBLIC - это аналог EXPORT и GLOBAL, но из других компиляторов. Потому как в Keil его нет.

Сорри. У меня почему-то отложилось в голове, что у Вас IAR.
Go to the top of the page
 
+Quote Post

6 страниц V  « < 4 5 6
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 25th June 2025 - 07:33
Рейтинг@Mail.ru


Страница сгенерированна за 0.01442 секунд с 7
ELECTRONIX ©2004-2016