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

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

И вы про атомарность. Это другой вопрос. Мухи отдельно, котлеты отдельно.
Реклама
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="ARV",url="/forum/viewtopic.php?p=3895001#p3895001"]так никто и не ответил, каким образом может измениться поведение этой функции с/без volatile, если данные по указателю эта функция не использует?[/uquote]
А зачем отвечать на странные вопросы, которые к теме в данном случае отношения не имеют? С тем же успехом вы бы могли требовать ответа на вопрос, как влияет частое употребление модификатора volatile на состав кишечных газов.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Напомню, что:
[uquote="a5021",url="/forum/viewtopic.php?p=3894133#p3894133"]Объясните, кто знает, плс, почему в неблокирующую функцию

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

HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
указатель на буфер pData передается без модификатора volatile ? Чет это на какой-то зашквар смахивает.[/uquote]
Вы сами начали задавать странные вопросы. Априори полагая, что volatile - правильно, а без него - какие-то выдуманные глюки и страдания будут.
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3895275#p3895275"]Априори полагая, что volatile - правильно, а без него - какие-то выдуманные глюки и страдания будут.[/uquote]
Чтобы не было глюков и страданий, нужно просто перестать всякими "халами" пользоваться!
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3895275#p3895275"]Вы сами начали задавать странные вопросы. Априори полагая, что volatile - правильно, а без него - какие-то выдуманные глюки и страдания будут.[/uquote]
Когда функция молча принимает неверные параметры, но ругается на верные, это выдуманные страдания? Ну поздравьте себя.

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3895318#p3895318"]Чтобы не было глюков и страданий, нужно просто перестать всякими "халами" пользоваться![/uquote]
Судя по тому, какое количество фанатов хала понабежало, говорить такие вещи здесь -- пустое дело.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

a5021 писал(а):Когда функция молча принимает неверные параметры, но ругается на верные, это выдуманные страдания?
Нет, это просто Вы передаёте ей неверные параметры.

Добавлено after 1 minute 32 seconds:
Eddy_Em писал(а):Чтобы не было глюков и страданий, нужно просто перестать всякими "халами" пользоваться!
А вот это - двумя руками поддерживаю. И автоматически причин к недовольству не будет.
Контактная информация:
Реклама
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3895325#p3895325"]Нет, это просто Вы передаёте ей неверные параметры.[/uquote]
Эти "неверные" ?

Изображение

Просите Мурика, быть может он сжалится и вышлет вам букварь про волатайл повторно.
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Да, неверные. Функция хочет указатель на uint8_t, а её передаётся массив volatile uint8_t. Вы используете функцию не по назначению.

Это как если бы в функцию, принимающую строку я захотел бы передать int. Ну вот просто потому, что считаю - что int - это good, а строки - это bad. Правда, тут warning-ом бы не обошлось - но это и бзик побольше.

P.S. По третьему примеру явно видно, что проблема не в функции, а в самом good_buffer:

Изображение
Контактная информация:
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3895340#p3895340"]Да, неверные. Функция хочет указатель на uint8_t, а её передаётся массив volatile uint8_t. Вы используете функцию не по назначению.[/uquote]
Для вас, поди, новость еще и то, что под DMA-трансфер переменная должна быть объявлена, как volatile ?
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Не должна.

P.S. Чтобы это звучало голословно, простой пример: периодически считываем результат преобразования АЦП микроконтроллера в буфер из, скажем, 4 элементов, постоянно и циклически. Цель иметь усредненённое значение последних 4 измерений, чтобы уменьшить шум преобразования. Тут совершенно не нужен volatile.
Контактная информация:
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3895346#p3895346"]Не должна.

P.S. Чтобы это звучало голословно, простой пример: периодически считываем результат преобразования АЦП микроконтроллера в буфер из, скажем, 4 элементов, постоянно и циклически. Цель иметь усредненённое значение последних 4 измерений, чтобы уменьшить шум преобразования. Тут совершенно не нужен volatile.[/uquote]
Вот эта ваша "не должна", она работает только для вашего примера или для любых случаев?
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

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

[uquote="WiseLord",url="/forum/viewtopic.php?p=3895346#p3895346"]Тут совершенно не нужен volatile.[/uquote]
Прошу прощения, но с чего вы решили, что компилятор не закеширует значение всех четырех измерений в регистрах и Вы в итоге не будете получать один и тот же результат, вообще не зависящий от результатов преобразования АЦП?
Друг Кота
Аватара пользователя
Сообщения: 4906
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

a5021 писал(а):Вот эта ваша "не должна", она работает только для вашего примера или для любых случаев?
Одного опровергающего примера уже достаточно, чтобы общее утверждение "DMA буфер должен быть всегда volatile" стало ложным.

Добавлено after 3 minutes 26 seconds:
ПростоНуб писал(а):с чего вы решили, что компилятор не закеширует значение всех четырех измерений в регистрах
Хотя бы с того, что в функции они мне нужны только один раз - прочитать и усреднить. При выходе эти регистры из стека уйдут, при повторном вызове фунций, снова попадут в стек и будут заполнены заново.
Контактная информация:
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

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

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

[uquote="WiseLord",url="/forum/viewtopic.php?p=3895364#p3895364"]При выходе эти регистры из стека уйдут, при повторном вызове фунций, снова попадут в стек и будут заполнены заново.[/uquote]
Ложное утверждение.
Если буфер DMA статический, то многие компиляторы вполне успешно умеют кешировать статические переменные в регистрах между вызовами функций. Вы даже не можете быть уверены, не заинлайнил ли компилятор Вашу функцию!
Если буфер DMA стековый (извращение, однако), то для начала, Вы получите предупреждение компилятора об обращении к неинициализированной переменной, а затем совсем не факт, что компилятор будет из этой неинициализированной переменной что-то читать. И нет никакой гарантии, что память в стеке под этот буфер вообще будет выделяться. Зачем, если под него можно выделить регистры?
Единственный надежный способ заставить компилятор читать что-то из памяти - это объявление volatile. В противном случае, оптимизатор сам решает, стоит ли вообще тратить время на обращение к памяти или обойтись регистрами.
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

Выдающимся специалистам по volatile втыкать до полного просвещения:

Изображение

...
...

Изображение

Кликабельно, если захочется подробностей.
Вложения
volatile2.png
(7.34 КБ) 681 скачивание
volatile.png
(32.07 КБ) 714 скачиваний
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18793
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Я так и не понял суть спора о параметрах функции: с моей точки зрения тип параметра показывает то, как этот параметр трактуется функцией, т.е. как она внутри себя его использует. Никакого доступа к данным массива внутри рассматриваемой функции нет, адрес этого массива просто заносится в регистр, и все! Это уже снаружи функции важно, чтобы компилятор не оптимизировал доступ к данным, а самой функции все равно!
Я с самого начала задаю вопрос: как квалификатор volatlile повлияет на запись адреса в регистр?! Никак. Поэтому этот указатель может (и, имхо, должен) быть void*, тогда по идее никаких проблем не будет ни с какой точки зрения.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="ARV",url="/forum/viewtopic.php?p=3895444#p3895444"]Я с самого начала задаю вопрос: как квалификатор volatlile повлияет на запись адреса в регистр?! Никак. Поэтому этот указатель может (и, имхо, должен) быть void*, тогда по идее никаких проблем не будет ни с какой точки зрения.[/uquote]
К стм-овским индусам 100% относится уже звучавшее "Мало кто из программистов хорошо понимает, как правильно использовать volatile." Вам же, похоже, и до их квалификации как до луны. Проблемы у вас не то, что будут, они уже сейчас стоят в полный рост. Тип указателя, в данном случае, ни на что не влияет и никаких проблем не устраняет.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18793
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

не надо обсуждать мои недостатки, недостатки индусов и т.п.
почему вы не возмущаетесь функцией memset - у нее параметры тоже не volatile! хотя "по смыслу" она очень похожа на работу рассматриваемой функции с DMA.

все дело именно в описании ИНТЕРФЕЙСА функции, т.е. её параметров: как функция должна себя вести, такой должен быть и интерфейс, чтобы не вводить программиста, не знакомого с её внутренним устройством, в заблуждение. если данная функция никак от режима оптимизации не меняет своё поведение, и это можно гарантировать и для будущих версий стандартов (поскольку никак нельзя оптимизировать начальную инициализацию регистра), то и требовать для неё какого-то особого интерфейса с намеком на зависимость от оптимизации, не корректно.

Добавлено after 3 minutes 24 seconds:
кстати, о проблемах: характерный источник проблем зачастую кроется именно в том, что написано не то, что подразумевается. и в данном контексте, как я уже говорил, лучший вариант интерфейса этой функции - указатель void*, демонстрирующий полное безразличие функции к данным по этому адресу.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

ARV, вы задаёте правильный, но очень неудобный вопрос. Именно поэтому вместо ответа на него получаете хамство и переход на личности.

За неимением HAL-а, накидал простенький пример, иллюстрирующий обсуждаемый вопрос.
Спойлер

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

void foo1(uint8_t * adr)
{
  DMA1_Channel1->CMAR = uint32_t(adr);
}

void foo2(volatile uint8_t * adr)
{
  DMA1_Channel2->CMAR = uint32_t(adr);
}

int main()
{     
  uint16_t buf1 = 101;
  volatile uint16_t buf2 = 102;

  // Никаких проблем с функциями в любых сочетаниях нет
  foo1((uint8_t *)&buf1);
  foo2((uint8_t *)&buf1);
  foo1((uint8_t *)&buf2);
  foo2((uint8_t *)&buf2);
  
  // Так должен себя вести буфер c DMA
  GPIOA->ODR = buf2;
  
  // А вот тут проблема!!!
  GPIOA->ODR = buf1;
  
  for(;;);
}
Посмотрим листинг?
Спойлер

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

//void foo1(uint8_t * adr)
//{
//  DMA1_Channel1->CMAR = uint32_t(adr);
_Z4foo1Ph:
        LDR.N    R1,??DataTable2  ;; 0x40020014
        STR      R0,[R1, #+0]
//}
        BX       LR               ;; return

//void foo2(volatile uint8_t * adr)
//{
//  DMA1_Channel2->CMAR = uint32_t(adr);
_Z4foo2PVh:
        LDR.N    R1,??DataTable2_1  ;; 0x40020028
        STR      R0,[R1, #+0]
//}
        BX       LR               ;; return

//int main()
//{     
main:
        SUB      SP,SP,#+4
//  uint16_t buf1 = 101;
//  volatile uint16_t buf2 = 102;;
        MOVS     R0,#+102
        STRH     R0,[SP, #+0]
 
// Никаких проблем с функциями в любых сочетаниях нет 
//  foo1((uint8_t *)&buf1);
        ADD      R1,SP,#+2
        LDR.N    R0,??DataTable2  ;; 0x40020014
        STR      R1,[R0, #+0]
// foo2((uint8_t *)&buf1);
        STR      R1,[R0, #+20]
//  foo1((uint8_t *)&buf2);
        STR      SP,[R0, #+0]
//  foo2((uint8_t *)&buf2);
        STR      SP,[R0, #+20]

// Так должен себя вести буфер c DMA
//  GPIOA->ODR = buf2;
        LDR.N    R0,??DataTable2_2  ;; 0x48000014
        LDRH     R1,[SP, #+0]
        STR      R1,[R0, #+0]
        
// А вот тут проблема!!!
//  GPIOA->ODR = buf1;
        MOVS     R2,#+101
        STR      R2,[R0, #+0]
//  for(;;);
??main_0:
        B.N      ??main_0
//}
Так и хочется процитировать классика: "Что, сынку, помогли тебе твои ляхи (volatile)?"
Ответить

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