STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение Аlex »

bob1, внутри функции (а точнее, в пределах блока кода {}), метка является локальной. И переход на неё возможен только в пределах этого блока.
Реклама
bob1
Мучитель микросхем
Сообщения: 453
Зарегистрирован: Ср июн 08, 2011 20:25:20
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение bob1 »

Задача такая. Есть цикл критичный по времени и внутри него нет возможности опроса глобальных переменных. При нормальном процессе цикл отрабатывает свои 1 сек и выходит. А если нажать на кнопку (прерывание) , хотелось бы быстрее выйти из этого цикла. Задумка была заменить адрес возврата из прерывания в стеке адресом за циклом.
Реклама
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: STM32 новичку в ARM что к чему

Сообщение COKPOWEHEU »

[uquote="bob1",url="/forum/viewtopic.php?p=4744646#p4744646"]Добрый день.
Есть функция . В ней метка к примеру aaa: . В Си (не переходя в asm) есть возможность определить ее адрес и присвоить глобальной переменной? &aaa не работает.
Пишу в IAR.[/uquote]

Код: Выделить всё

void *l;

int main(){
  printf("1\n");
  l = &&aaa;
  goto *l;
  printf("2\n");
aaa:
  printf("%p\n", l);
}
Правда, применений этому я не вижу. И оптимизации все попортят, и пролог-эпилог у функций, и вообще высокоуровневость языка. Вы же не знаете, в какие команды развернется код до метки и после.

Добавлено after 3 minutes 41 second:
[uquote="bob1",url="/forum/viewtopic.php?p=4744664#p4744664"]Задумка была заменить адрес возврата из прерывания в стеке адресом за циклом.[/uquote]
Скорее всего, не сработает. Мало ли какие переменные компилятор успеет положить на стек в промежутке.
Лучше покажите как организован сам цикл и что же за такая задача, что нужно отсчитывать секунду, но при этом нельзя проверять переменные.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: STM32 новичку в ARM что к чему

Сообщение jcxz »

[uquote="bob1",url="/forum/viewtopic.php?p=4744664#p4744664"]Задумка была заменить адрес возврата из прерывания в стеке адресом за циклом.[/uquote]А если адрес возврата не в стеке? В ARM адрес возврата изначально находится в LR и в стек попадает не всегда. Учите матчасть архитектуру ARM! 8)

Если уж так хочется выскочить из цикла при помощи ISR, то можно:
1) до вызова (CALL) процедуры с циклом, сохранить регистры R4-R11,LR,SP(соответствующий) в глобальную переменную;
2) найти начало стека прерываний, найти адрес возврата в нём;
3) если он - внутри прерываемой функции - подменить его на адрес кода, который восстановит сохранённые ранее регистры и сделает переход на команду за CALL.
Это если не используется FPU. Если используется - регистров сохранять/восстанавливать нужно больше.

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

PS: В качестве простого решения, доступного даже начинающему, можно посоветовать для того мега-цикла создать отдельную задачу ОС. Когда нужно преждевременно выйти из цикла: из ISR активируем другую задачу (управляющую), с более высоким приоритетом, и в ней - убиваем прерываемую задачу. Всё.
Ну или можно даже не убивать, а из управляющей задачи отредактировать контекст задачи мега-цикла.
Реклама
Эиком - электронные компоненты и радиодетали
bob1
Мучитель микросхем
Сообщения: 453
Зарегистрирован: Ср июн 08, 2011 20:25:20
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение bob1 »

[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4744669#p4744669"]Лучше покажите как организован сам цикл[/uquote]
Вот что получилось.
Спойлер

Код: Выделить всё

__no_init  uint32_t* p_stek;
uint32_t flag_stek;

void TEST(uint32_t n)@".ccmram"  
{

      p_stek=(uint32_t*)__get_MSP(); // текущий адрес вершины стека 
      flag_stek=1;  // флаг

.....здесь заполнение регистров данными. Стек не меняется. Смотрел в asm листинге.
 
 do{
    Нет переходов на другие функции.
    Работа только с регистрами. Стек не меняется. Смотрел в asm листинге.
	Накопление данных. Если прерывание, то данные не нужны.
	n--;
    }
 while (n!=0) ;
	
	... сохранение данных из регистров. Стек не меняется.
   
aaa:

};

void EXTI9_5_IRQHandler(void){ // STM32G431
 .....обработка прерывания
 
   if(flag_stek>0){
     flag_stek=0;       
     p_stek=p_stek-26; // устанавливаем адрес на сохранённый R0 в стеке
     *p_stek=1; // счетчик цикла n=1;
   };
    t_50mc;
;
jcxz писал(а): в стек попадает не всегда
Не знал. Учимся.. :)) Адрес в стеке уже был найден. Нужно было только значение метки.
jcxz писал(а): Если уж так хочется выскочить из цикла при помощи ISR, то можно: 1) ....
Надо попробовать.
jcxz писал(а): из ISR активируем другую задачу (управляющую), с более высоким приоритетом, и в ней - убиваем прерываемую задачу.
Это на языке С или С++ ??
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение Аlex »

bob1 писал(а):Вот что получилось.
Вы не поняли. Вас попросили показать сам цикл, из которого нет возможности выйти по какому-нибудь флагу.
Интересно, что это за цикл такой ...
Реклама
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: STM32 новичку в ARM что к чему

Сообщение jcxz »

[uquote="bob1",url="/forum/viewtopic.php?p=4744909#p4744909"]Вот что получилось.

Код: Выделить всё

      p_stek=(uint32_t*)__get_MSP(); // текущий адрес вершины стека 
      flag_stek=1;  // флаг

...

   if(flag_stek>0){
     flag_stek=0;       
     p_stek=p_stek-26; // устанавливаем адрес на сохранённый R0 в стеке
     *p_stek=1; // счетчик цикла n=1;
   };
    t_50mc;
;
[/uquote]Это говнокод. Так делать нельзя. Компилятор может в любой момент поменять код и ваша программа рухнет.

Добавлено after 3 minutes 2 seconds:
[uquote="bob1",url="/forum/viewtopic.php?p=4744909#p4744909"]Нужно было только значение метки.[/uquote]Оно вам никак не поможет. Тем более что после компиляции никаких меток уже не существует.
[uquote="bob1",url="/forum/viewtopic.php?p=4744909#p4744909"]
jcxz писал(а): из ISR активируем другую задачу (управляющую), с более высоким приоритетом, и в ней - убиваем прерываемую задачу.
Это на языке С или С++ ??[/uquote]Язык не важен. Это возможности, которые даёт РТОС.

Добавлено after 1 minute 54 seconds:
PS: [uquote="bob1",url="/forum/viewtopic.php?p=4744909#p4744909"]

Код: Выделить всё

__no_init  uint32_t* p_stek;
uint32_t flag_stek;
[/uquote]Переменные, с которыми идёт работа в разных процессах (например - в фоновой задаче и в ISR), следует объявлять с квалификатором 'volatile'. Это следует запомнить как "Отче наш".

Добавлено after 3 minutes 16 seconds:
[uquote="bob1",url="/forum/viewtopic.php?p=4744909#p4744909"]

Код: Выделить всё

    t_50mc;
;
[/uquote]Здесь тоже баг.
bob1
Мучитель микросхем
Сообщения: 453
Зарегистрирован: Ср июн 08, 2011 20:25:20
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение bob1 »

[uquote="Аlex",url="/forum/viewtopic.php?p=4744962#p4744962"]Вы не поняли. Вас попросили показать сам цикл, из которого нет возможности выйти по какому-нибудь флагу.[/uquote] Пусть для примера будет программный DDS генератор. Программа крутиться во while(1){} и нужно как-то выйти.
Просто это уход в сторону от поставленной задачи. Куда поставить в цикл 3 строчки кода (чтение, сравнение, переход), которые при правильном расположении займут 3 такта у меня опыт есть. Можно сделать и счетчик цикла глобальной переменной, то тогда можно обойтись и 2 доп. тактами (чтение, запись). Из минусов: дополнительно занят 1 регистр для адреса счетчика цикла.
Adrift
Вымогатель припоя
Сообщения: 540
Зарегистрирован: Вт окт 01, 2024 15:22:33

Re: STM32 новичку в ARM что к чему

Сообщение Adrift »

bob1, если прямо максимально быстро нужно, тогда и обработчик прерываний и таблицу векторов в CCM пихайте, а не только свою функцию.
bob1
Мучитель микросхем
Сообщения: 453
Зарегистрирован: Ср июн 08, 2011 20:25:20
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение bob1 »

[uquote="jcxz",url="/forum/viewtopic.php?p=4744987#p4744987"]Это говнокод.[/uquote] Согласен, что это костыль.
[uquote="jcxz",url="/forum/viewtopic.php?p=4744987#p4744987"]меток[/uquote] С этим уже разобрались :) .
[uquote="jcxz",url="/forum/viewtopic.php?p=4744987#p4744987"]'volatile'[/uquote] Учту.
Adrift писал(а):если прямо максимально быстро нужно, тогда и обработчик прерываний и таблицу векторов в CCM пихайте, а не только свою функцию.
Таблица там, как некоторые обработчики, от которых требуется быстродействие. А обработка кнопки может и во флеши сидеть. Нужно дождаться окончания дребезга. Основное быстродействие нужно в цикле.
Аватара пользователя
JackSmith
Потрогал лапой паяльник
Сообщения: 332
Зарегистрирован: Ср мар 09, 2016 08:07:41

Re: STM32 новичку в ARM что к чему

Сообщение JackSmith »

[uquote="bob1",url="/forum/viewtopic.php?p=4744646#p4744646"]Есть функция . В ней метка к примеру aaa: . В Си (не переходя в asm) есть возможность определить ее адрес и присвоить глобальной переменной? &aaa не работает.
Пишу в IAR.[/uquote]

за то, по какому физическому адресу располагается тот или иной код, отвечает не компилятор, а компоновщик. про и IAR ничего не скажу, но в gcc можно вставить директиву __attribute__((section(".my_section"))) и дальше код пойдет с определенного адреса. обычно используется для размещения таблицы векторов. т.е. через скрипт компоновщика жестко привязать код к определенному адресу, полагаю, что можно.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: STM32 новичку в ARM что к чему

Сообщение jcxz »

[uquote="bob1",url="/forum/viewtopic.php?p=4745003#p4745003"]Куда поставить в цикл 3 строчки кода (чтение, сравнение, переход), которые при правильном расположении займут 3 такта у меня опыт есть. Можно сделать и счетчик цикла глобальной переменной, то тогда можно обойтись и 2 доп. тактами (чтение, запись). Из минусов: дополнительно занят 1 регистр для адреса счетчика цикла.[/uquote]Так если дополнительные пара тактов в теле цикла - не проблема, то зачем тогда весь этот огород?
Сделать:

Код: Выделить всё

static u8 volatile flag = 0;
do {
  ...
  if (flag) break;
} while (--n);
Это добавит в код цикла всего две дополнительные команды: LDRB Rx, Rbase; CBNZ Rx,... которые в цикле будут занимать 2 или 3 такта (в зависимости от спаривания с соседними командами). Эту проверку лучше расположить ближе к концу цикла (чтобы была использована именно единственная CBNZ, а не пара CMP+BNE).

Если переменная 'flag' не находится в сегменте данных, в котором находятся рабочие переменные остального кода цикла, то конечно добавится ещё одна команда - предварительная загрузка Rbase указателем на 'flag' из секции кода: LDR Rbase, [PC, ...]. Но можно расположить 'flag' возле данных, обрабатываемых циклом. Тогда эта дополнительная LDR не будет нужна.

Добавлено after 6 minutes 28 seconds:
[uquote="JackSmith",url="/forum/viewtopic.php?p=4745013#p4745013"]в gcc можно вставить директиву __attribute__((section(".my_section"))) и дальше код пойдет с определенного адреса. обычно используется для размещения таблицы векторов. т.е. через скрипт компоновщика жестко привязать код к определенному адресу, полагаю, что можно.[/uquote]В компоновщике IAR такое тоже можно.

Кстати: Расположение и исполнение кода из ОЗУ даёт возможность адресовать через PC не только константы, но и переменные. И за счёт этого оптимизировать код (если можно адресоваться к переменным через PC, то не нужно будет грузить и держать в регистре указатель на секцию статических данных).
Adrift
Вымогатель припоя
Сообщения: 540
Зарегистрирован: Вт окт 01, 2024 15:22:33

Re: STM32 новичку в ARM что к чему

Сообщение Adrift »

[uquote="bob1",url="/forum/viewtopic.php?p=4745011#p4745011"]Таблица там, как некоторые обработчики, от которых требуется быстродействие. А обработка кнопки может и во флеши сидеть. Нужно дождаться окончания дребезга. Основное быстродействие нужно в цикле.[/uquote]
Выше вы писали, что если нажать на кнопку, то хотелось бы быстрее выйти из этого цикла...
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: STM32 новичку в ARM что к чему

Сообщение jcxz »

[uquote="bob1",url="/forum/viewtopic.php?p=4745011#p4745011"]Нужно дождаться окончания дребезга. Основное быстродействие нужно в цикле.[/uquote]Если нужно "выходить из цикла по нажатию кнопки", то зачем "дожидаться окончания дребезга"?
Как только с кнопки получен первый импульс нажатия - значит очевидно её начали нажимать. И неважно сколько она затем будет дребезжать. Можно вообще обойтись без прерывания: читать в цикле сразу регистр GPIO ноги кнопки и выходить из цикла по первому импульсу дребезга. А "дожидаться окончания дребезга" - уже вне цикла.

Добавлено after 9 minutes 30 seconds:
PS: Пришёл в голову ещё более короткий и быстрый вариант выхода из цикла:

Код: Выделить всё

static s32 volatile flag = 1;
s32 n = N - 1; //N - штатное кол-во проходов цикла
do {
  ...
} while ((n -= flag) >= 0);
В ISR для прерывания цикла нужно просто записать во 'flag' значение == N.
Такой код должен добавить к циклу только одну дополнительную команду LDR Rx,[flag]. Которая займёт 1 или 2 такта.
bob1
Мучитель микросхем
Сообщения: 453
Зарегистрирован: Ср июн 08, 2011 20:25:20
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение bob1 »

[uquote="jcxz",url="/forum/viewtopic.php?p=4745015#p4745015"]Так если дополнительные пара тактов в теле цикла - не проблема[/uquote] Проблема. Так получилось, что процессор должен работать на частотах кратным 2. С этими 2 тактами приходиться работать на 65,536 МГц. Без них на 32,768МГц.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745015#p4745015"]Если нужно "выходить из цикла по нажатию кнопки", то зачем "дожидаться окончания дребезга" ?Как только с кнопки получен первый импульс нажатия ...[/uquote] Идея понятна. В каких вариантах наверно можно применить. Но после выхода из цикла прога обновляет новые входные параметры и опять уходит в заплыв в этот цикл. Сделать загрузку входных данных во время дребезга, а прерывание включать перед входом в цикл.
[uquote="jcxz",url="/forum/viewtopic.php?p=4745015#p4745015"]Пришёл в голову ещё более короткий и быстрый вариант выхода из цикла:[/uquote] Надо попробовать и посмотреть листинг.
Adrift писал(а): хотелось бы быстрее выйти из этого цикла
Имелось виду не дожидаясь нормального окончания работы его.
Аватара пользователя
GARMIN
Держит паяльник хвостом
Сообщения: 953
Зарегистрирован: Вс дек 02, 2012 16:58:33
Откуда: от туда
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение GARMIN »

ИМХО вы пытаетесь натянуть сову на глобус. Или другими словами АТмеловский подход с подсчётом тактов на АРМ процессор с конвейером.
Займитесь чем-нибудь полезным.
Подсчёт тактов при 160МГц тактовой и периоде процесса 1 секунда, и нажатии кнопки... За сколько тысяч тактов процессора вы нажмёте кнопку?
Невозможность читать глобальные переменные в прерывании при едином адресном пространстве? Пишите исчо!
bob1
Мучитель микросхем
Сообщения: 453
Зарегистрирован: Ср июн 08, 2011 20:25:20
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение bob1 »

[uquote="GARMIN",url="/forum/viewtopic.php?p=4745144#p4745144"]другими словами АТмеловский подход с подсчётом тактов на АРМ процессор с конвейером.[/uquote] Пересел с XMega на ARM. Подход остался прежним....
[uquote="GARMIN",url="/forum/viewtopic.php?p=4745144#p4745144"]Займитесь чем-нибудь полезным.[/uquote] А мозги потренировать!!??
[uquote="GARMIN",url="/forum/viewtopic.php?p=4745144#p4745144"]Подсчёт тактов при 160МГц.[/uquote] Для портативного устройства или проц. работает на 128МГц или на 32МГц разница есть.
[uquote="GARMIN",url="/forum/viewtopic.php?p=4745144#p4745144"]Невозможность читать глобальные переменные в прерывании при едином адресном пространстве? Пишите исчо![/uquote] Ну если бы они были, то и диспута не было. Разговор шел сделать без них :))
з.ы.
По поводу тактов возник вопрос.
Команда LDR R0,[R1, #+0]; лежит уже в конвейере. До нее и после команд чтения и записи нет. За сколько тактов должна обработаться? За 2 или 3? процессор STM32G431.
Аватара пользователя
JackSmith
Потрогал лапой паяльник
Сообщения: 332
Зарегистрирован: Ср мар 09, 2016 08:07:41

Re: STM32 новичку в ARM что к чему

Сообщение JackSmith »

[uquote="bob1",url="/forum/viewtopic.php?p=4745220#p4745220"]Команда LDR R0,[R1, #+0]; лежит уже в конвейере. До нее и после команд чтения и записи нет. За сколько тактов должна обработаться? За 2 или 3? процессор STM32G431.[/uquote]

на разных частотах одни и те же инстркуции могут выполняться за разное количесво тактов. зависит от flash latency для данной частоты.
bob1
Мучитель микросхем
Сообщения: 453
Зарегистрирован: Ср июн 08, 2011 20:25:20
Контактная информация:

Re: STM32 новичку в ARM что к чему

Сообщение bob1 »

[uquote="JackSmith",url="/forum/viewtopic.php?p=4745229#p4745229"]flash latency для данной частоты[/uquote]Она уже загружена в контейнер и ждет своего выполнения т.е. уже "flash latency" программа уже прошла. Идет процесс без задержек, линейное выполнение программы, без переходов.
tonyk
Это не хвост, это антенна
Сообщения: 1309
Зарегистрирован: Вт ноя 19, 2019 06:10:18

Re: STM32 новичку в ARM что к чему

Сообщение tonyk »

bob1 писал(а):Для портативного устройства или проц. работает на 128МГц или на 32МГц разница есть.
Когда-то занимался портативными приборами, использовал ADuC8xx. Когда ждал нажатия кнопки на приборе, тактировал ядро 32кГц (килогерц). Когда работал АЦП, вообще отключал тактирование всего, кроме АЦП. А вот для выполнения расчётов выводил ядро на максимальные 12МГц (мегагерц). В МК на ARM очень гибкая система тактирования, позволяющая управлять частотой не только процессора, но и шин, и периферии. Если занимаетесь портативной техникой, то без этого никак не обойтись.
Ответить

Вернуться в «ARM»