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

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

[uquote="Мурик",url="/forum/viewtopic.php?p=3455976#p3455976"]Напишите ему как ее сделать.[/uquote]
LDREX/STREX чем не устраивает?
Реклама
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

[uquote="jcxz",url="/forum/viewtopic.php?p=3455975#p3455975"][uquote="Мурик",url="/forum/viewtopic.php?p=3455956#p3455956"]Маловероятно. Сбрасывайте через BitBanding (если флаг это один бит в переменной) если установлен.[/uquote]
А смысл? Проверка-сброс бита в плане атомарности ничем не отличается от проверки-сброса переменной. И то и другое - неатомарные операции. Автор же хочет атомарную операцию проверка-сброс.[/uquote] Может я неудачно выразился...

Еще со времен PDP-11 я решал задачи управления чем-либо в реальном времени так: основная программа - своего рода диспетчер задач - в своем основном цикле проверяет флажки готовности задач, при появлении кого-то из них очищает его и вызывает короткую подпрограмму действий по этому флажку. Взводятся же эти флажки в программах обслуживания прерываний. Они вообще предельно короткие: сняли байт данных с регистра аппаратуры (если надо, конечно), взвели флажок, что этот байт поступил, и RTI.

Из-за особенностей команды ожидания PDP-11 при такой организации главного цикла переводить процессор в состояние ожидания было нельзя. Да, в общем-то это было и неактуально - и Э-60, и ДВК жрали электричество, как свинья помои, о батарейном питании можно было и не мечтать. Позже, на АВР, я добавил в этот нехитрый алгоритм примитивной многозадачки ожидание - если ни одной активной задачи не найдено, sleep(). Естественно, дОлжным образом манипулируя разрешениями и запрещениями прерываний, где надо.

Сейчас я планирую нечто подобное развернуть на STM32, вот и спрашиваю.

Ставить "взрослую" RTOS смысла не вижу - предстоящие задачи достаточно примитивны. Как-то специально использовать доступную многоуровневость системы прерываний тоже не собираюсь, из тех же соображений.

Так, что мне нужно простейшее действие - пробежавшись по таблице задач и не найдя готовой, грамотно заснуть.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

[uquote="afz",url="/forum/viewtopic.php?p=3456644#p3456644"]проверяет флажки готовности задач, при появлении кого-то из них очищает его[/uquote]
На вопрос ответьте, пожалуйста.
ПростоНуб писал(а):LDREX/STREX чем не устраивает?
Этот механизм в STM32 именно для таких задач и заточен.
Мудрый кот
Сообщения: 1846
Зарегистрирован: Вт авг 15, 2017 10:51:13

Сообщение jcxz »

[uquote="afz",url="/forum/viewtopic.php?p=3456644#p3456644"]Так, что мне нужно простейшее действие - пробежавшись по таблице задач и не найдя готовой, грамотно заснуть.[/uquote]
Для такой задачи атомарность установки-сброса флажков не нужна. Bit-band нужен только если эти флажки сделать битовыми, но это имеет смысл только если задач большое количество (тогда можно быстрее обнаруживать установленный бит считав 32-битное слово и воспользовавшись командой CLZ). Если без ОС, то процесс, ждущий флажков, лучше оформить в виде ISR возбуждаемого программно. Приоритет этого прерывания должен быть ниже любого из прерываний, устанавливающих флажки. Собственно так получается аналог ОС, но с одной задачей (ISR диспетчера).
Процесс, ждущий флажков, можно конечно сделать и простым бесконечным циклом.
В ISR-ах, устанавливающих флажки, установка флажка должна сопровождаться программным возбуждением прерывания (через NVIC).
Примерно так:
Спойлер

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

#define BITBAND_RAM_ALIAS_BASE  0x22000000 //0x22000000-0x2234FFFF
#define BITBAND_RAM_REGION_BASE 0x20000000 //0x20000000-0x2006FFFF
#define BITBAND_IO_ALIAS_BASE   0x42000000 //0x42000000-0x43FFFFFF
#define BITBAND_IO_REGION_BASE  0x40000000 //0x40000000-0x400FFFFF

#define BITBAND(addr, bit, R, A) \
  ((u32 *)((u32)(addr) - (R) + ((A) >> 5) << 5) + (bit))
#define BITBAND_IO(addr, bit) \
  BITBAND(addr, bit, BITBAND_IO_REGION_BASE, BITBAND_IO_ALIAS_BASE)
#define BITBAND_RAM(addr, bit) \
  BITBAND(addr, bit, BITBAND_RAM_REGION_BASE, BITBAND_RAM_ALIAS_BASE)

//Установка состояния ожидания для прерывания num
#define IntSet(num) { NVIC.SETPEND[(num) >> 5] = 1u << ((num) & 0x1F); }

enum { //флаги задач; приоритет обработки уменьшается с ростом номера флага, TASK0 - максимальный приоритет
  TASK0, TASK1, TASK2, ..., TASK_n}; //TASK_n должно быть <=32
u32 volatile tasksPend @ ".BITBAND_RAM" = 0; //секцию .BITBAND_RAM с помощью командного файла компоновщика расположить в области ОЗУ, поддерживающей bit-band

extern "C" void isrDispetcher() //ISR диспетчера
{
  u32 j;
  while (j = tasksPend) {
    uint i = __CLZ(__RBIT(j)); //получаем номер наиболее приоритетного из установленных флагов задач
    BITBAND_RAM(tasksPend, i) = 0; //сбросим этот флаг
    switch (i) {
      case TASK0: /* обработка для TASK0 */ break;
      case TASK1: /* обработка для TASK1 */ break;
      case TASK2: /* обработка для TASK2 */ break;
    }
  }
}

extern "C" void isrTask0()
{
  BITBAND_RAM(tasksPend, TASK0) = 1; //установим свой флаг
  IntSet(NVIC_VECTOR_FOR_DISPETCHER);
  //сделаем полезную работу
}
Если в Вашем МК не реализован bit-band, то можно этот код переделать под вариант на LDREX/STREX или на критических секциях (запретах прерываний).
Также, если задач - малое количество, можно перейти на char-флаги, вместо битовых как тут.

При этом в фоновом процессе (функция main()) после инициализации всей этой системы просто зацикливаетесь в цикле: while (1) __WFE();
Или установив бит SLEEPONEXIT в System Control Register ядра Cortex-M можно избавиться от этого цикла.
А также фоновый процесс (main()) можно использовать для измерения загрузки CPU: бесконечно инкрементировать счётчик, защёлкивая его через равные промежутки времени и находя отношение защёлкнутого значения к значению для случая когда процессор простаивает (измеряется предварительной калибровкой).
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="jcxz",url="/forum/viewtopic.php?p=3456724#p3456724"]Если без ОС, то процесс, ждущий флажков, лучше оформить в виде ISR возбуждаемого программно. Приоритет этого прерывания должен быть ниже любого из прерываний, устанавливающих флажки. Собственно так получается аналог ОС, но с одной задачей (ISR диспетчера).
Процесс, ждущий флажков, можно конечно сделать и простым бесконечным циклом.
В ISR-ах, устанавливающих флажки, установка флажка должна сопровождаться программным возбуждением прерывания (через NVIC).[/uquote]
В кортексах есть PendSV - это как раз прерывание генерируемое программно, для чего нужно включить соответствующий бит:

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

SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
Фактически можно в основном цикле проверять низкоприоритетные флаги, обработчики которых могут занимать длительное время, при этом периодически в прерывании таймера(и/или в обработчиках других прерываний) генерить PendSV и в нем запускать более приоритетные задачи, причем в самом прерывании таймера можно обрабатывать задачи с приоритетов выше тех, которые выполняются в PendSV, т.е. уже получилось 3 приоритета, если не считать полтора десятка приоритетов всех остальных прерываний.
Реклама
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="Reflector",url="/forum/viewtopic.php?p=3456760#p3456760"]Фактически можно в основном цикле проверять низкоприоритетные флаги, обработчики которых могут занимать длительное время[/uquote]
Каким-то полингом попахивает. :)
Реклама
Мудрый кот
Сообщения: 1846
Зарегистрирован: Вт авг 15, 2017 10:51:13

Сообщение jcxz »

[uquote="Reflector",url="/forum/viewtopic.php?p=3456760#p3456760"]В кортексах есть PendSV - это как раз прерывание генерируемое программно[/uquote]
Да - оптимально использовать его. Но можно и любой другой свободный вектор.
Можно вообще для каждого флага свой диспетчер сделать со своим вектором прерывания, возбуждаемым программно из аппаратного ISR.

[uquote="Reflector",url="/forum/viewtopic.php?p=3456760#p3456760"]Фактически можно в основном цикле проверять низкоприоритетные флаги, обработчики которых могут занимать длительное время, при этом периодически в прерывании таймера(и/или в обработчиках других прерываний) генерить PendSV и в нем запускать более приоритетные задачи, причем в самом прерывании таймера можно обрабатывать задачи с приоритетов выше тех, которые выполняются в PendSV, т.е. уже получилось 3 приоритета, если не считать полтора десятка приоритетов всех остальных прерываний.[/uquote]
Это уже эмуляция подобия РТОС. 8) Лучше тогда уж автору освоить любую готовую РТОС.
А фоновый процесс лучше использовать для измерения загрузки CPU.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

uldemir, весьма смешны ваши потуги с калокубом и совершенно не понятно нежелание изучать железо.

HAL_TIM_Base_Start_DMA - эта хрень только конфигурирует реквесты UP к DMA.
Все остальное - источник и приемник , размер данных, источник реквестов и счетчик конфигурируется в канале DMA , это если F1 в F4 -потоки.

Все делается просто и прозрачно.
Непонятно только зачем BSSR , для него надо специально подготавливать буфер.

Для чипов с каналами DMA:
Конфигурим таймер как счетчик вверх с включением реквеста DMA.
Конфигурим канал DMA .

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

void Init_TIM3(void)
{
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;   // TIM3 clock enable

TIM3->PSC  = (SystemCoreClock/(DIGITS * 50 * 1000)) - 1;  //240 
TIM3->ARR  = 1000 - 1;

              
        
TIM3->DIER  |= TIM_DIER_UDE;                    // Upload DMA Enable

        
TIM3->CR1   |= TIM_CR1_CEN | TIM_CR1_ARPE;      // Counter Enable

}


void Init_DMA(void)
{    
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
    
DMA1_Channel3->CPAR = (uint32_t)&GPIOA->BSSR;     // DMA channel x peripheral address register
DMA1_Channel3->CMAR = (uint32_t)Data_Buffer;     // DMA channel x memory address register    
DMA1_Channel3->CNDTR = DIGITS;                   // DMA channel x number of data register

DMA1_Channel3->CCR  |=  DMA_CCR_MSIZE_0;         // Memory size 16 bit
DMA1_Channel3->CCR  |=  DMA_CCR_PSIZE_0;         // Peripheral size 16 bit

DMA1_Channel3->CCR  |=  DMA_CCR_PL_1;            // Channel Priority level High 
DMA1_Channel3->CCR  |=  DMA_CCR_MINC;            // Memory increment mode 
DMA1_Channel3->CCR  |=  DMA_CCR_CIRC;            // Circular mode
DMA1_Channel3->CCR  |=  DMA_CCR_DIR;             // Data transfer direction Memory -> Peripheral

DMA1_Channel3->CCR  |=  DMA_CCR_EN;              // Channel enable
}

Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

В калокубе учить не надо ничего типо. Их манит это как мух на гавно.
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

Учить там надо все равно. Только изучать придется не железо и техники обращения с ним, а весьма необычные представления индусов о прекрасном (HAL).
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Я с STM32 только начал активно знакомиться. И как по мне - CubeMX достаточно хорош для того, чтобы в сторонке от основного проекта сгенерировать код инициализации какой-нибудь периферии, чтобы можно было подсмотреть некоторые приёмы использования.

В частности, в интернете везде кругом используют либо устаревший SPL, либо тяжеловесный HAL. А такая альтернатива, как LL (low-level library), как-то мало описана. И CubeMX, позволяющий сгенерировать код с ней, является достаточно неплохим подспорьем.

Но, опять же повторю - в моём случае - только как генератор кода, который можно подсмотреть, но не тащить весь генерированный код в свой проект.
Контактная информация:
Мудрый кот
Сообщения: 1846
Зарегистрирован: Вт авг 15, 2017 10:51:13

Сообщение jcxz »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3457280#p3457280"]в интернете везде кругом[/uquote]
Не говорите за всех! Нигде и никогда не использовал никаких библиотек для общения с периферией. Исключительно - даташит и юзермануал.
В "библиотеках" обычно нуждаются те, кто не в состоянии сам понять по мануалу как работает периферия.
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

WiseLord, любители гоуту выбирают калокуб? Это уже диагноз...

Что помешало лично вам изучить железо? Тоскливое наследство avr или догмы вашего гуру ARV?
Без калокубов и прочей визуальной хрени , используя только документацию от вендора, вменяемо изучается любой камень.

На данный момент - STM32, NXP, NRF от нордика, на подходе GD32 и HC32...

Но вы продолжайте тыкать в калокубе...

[uquote="WiseLord",url="/forum/viewtopic.php?p=3457280#p3457280"]Но, опять же повторю - в моём случае - только как генератор кода, который можно подсмотреть, но не тащить весь генерированный код в свой проект.[/uquote]

С калокубом не получиться быть частично беременной, или вы юзаете г.код, либо нет. Ничего полезного из него не взять...
Последний раз редактировалось dosikus Сб сен 15, 2018 10:34:18, всего редактировалось 1 раз.
Друг Кота
Аватара пользователя
Сообщения: 7383
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

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

Для совершенно невменяемых - мне нужно сделать совместимыми с кубовским инитом сие строчки:

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

	// TIM4 - PWM for display.
		// Настроить ARR - коэффициент деления частоты сканирования индикации.
		TIM4->CR1 &= ~TIM_CR1_CEN ; // disable timer
		TIM4->PSC = 0;
		TIM4->ARR = 10928-1; // 8MHz / 10928 = 732Hz / 5 = 146 Hz
		TIM4->CR1 |= TIM_CR1_URS |  TIM_CR1_ARPE ; // only overfow generate UEV
		TIM4->DIER |= TIM_DIER_UDE | TIM_DIER_UIE; // Update DMA enable.
		TIM4->CR1  |= TIM_CR1_CEN   ; //enable timer
	}
	if (phase == 2) {
		// Канал 7 ПДП для динамической индикации (из ОЗУ в GPIO)
		// Настроить CPAR, если используется другой GPIO
		DMA1_Channel7->CPAR = (uint32_t) (&(GPIOA->BSRR)); // (3)
		DMA1_Channel7->CMAR = (uint32_t)(videobuff); // (4)
		DMA1_Channel7->CNDTR = MAXGRID; // (5) 
		DMA1_Channel7->CCR |= DMA_CCR7_MINC | DMA_CCR7_MSIZE_1 | DMA_CCR7_PSIZE_1 | DMA_CCR7_CIRC | DMA_CCR7_DIR | DMA_CCR7_TCIE; // (6)  
		DMA1_Channel7->CCR |= DMA_CCR7_EN; // (7) 
	}
Вопрос как, так как особо вкуриваться в HAL мне не охота.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

uldemir , лучше описать что нужно в итоге ...
Если нужна аппаратная динамическая индикация на LED , то все уже сляпано -см. пост №8 http://kazus.ru/forums/showthread.php?t=107109
С городками и официантками...

[uquote="uldemir",url="/forum/viewtopic.php?p=3457305#p3457305"]Для совершенно невменяемых - мне нужно сделать совместимыми с кубовским инитом сие строчки:[/uquote]

Там где вы взяли этот код нет инита?
И невменяемого скрещивать адекватный код с калокубом...
Мудрый кот
Сообщения: 1846
Зарегистрирован: Вт авг 15, 2017 10:51:13

Сообщение jcxz »

[uquote="dosikus",url="/forum/viewtopic.php?p=3457299#p3457299"]WiseLord, любители гоуту выбирают калокуб? Это уже диагноз...
На данный момент - STM32, NXP, NRF от нордика, на подходе GD32 и HC32...[/uquote]
Хех!:
NXP (LPC17xx, LPC43xx), Tiva (TM4C129), OMAP-L137 (ARM9+DSP+PRUSS), TMS320VC5502, MSP430FR5xx, STM32F4xxx/STM32F103, STM8S, XMC4500/4700 - и везде только мануал и даташит. 8)
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

jcxz, ну вот же. А тут тыркаются болезные в калокубе ...
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3457280#p3457280"]Я с STM32 только начал активно знакомиться. И как по мне - CubeMX достаточно хорош для того, чтобы в сторонке от основного проекта сгенерировать код инициализации какой-нибудь периферии, чтобы можно было подсмотреть некоторые приёмы использования.[/uquote]
Посмотреть можно, но вот увидеть что-либо полезное довольно затруднительно. Куб сначала генерирует инициализацию неких объемных структур, универсальных, по замыслу индусов, для всей линейки и всех семейств, а затем, крайне непрозрачным способом переваливает данные из этих структур, собственно, в регистры МК. Получается каша и какая-то жуткая дребедень, где дефолтные значения регистров переписываются точно такими же значениями, а бывает, что и по нескольку раз. Глядя на структуры инициализации, нет никакой возможности понять, какие из полей для конкретного МК надо заполнять, т.к. структуры универсальные и полей там на все случаи жизни. И получается полная хрень -- для того, чтобы полноценно использовать HAL, по хорошему, надо и сам HAL знать хорошо и знание железа никак не обойти. По факту, нужно изучать два разных представления одного и того же. Очевидно, что это избыточно и совершенно ни к чему.

Куб был бы хорош, если бы генерировал регистровые инициализации. Компактные, с комментариями, похожие на то, что мог бы написать квалифицированный программист. Это был бы отличный иллюстратор к референсу и замечательное подспорье для обучения. К сожалению, на данный момент даже с учетом внедрения LL, куб еще слишком далек от этой цели.
Друг Кота
Аватара пользователя
Сообщения: 3386
Зарегистрирован: Пн окт 11, 2010 19:00:08

Сообщение Мурик »

Не все же такие задроты как вы. :)))
Кроме МК есть другие дела. :)
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Мурик, изучаю время от времени или в обеденный перерыв либо когда есть время в выходные.
Насчет задротов- проще и действенней изучить матчасть чем над**чивать в калокубе.
А любовь к барсикам и визуальным тыкалкам тебя всегда подводит...
Ответить

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