Эти "неверные" ?
Просите Мурика, быть может он сжалится и вышлет вам букварь про волатайл повторно.
Одного опровергающего примера уже достаточно, чтобы общее утверждение "DMA буфер должен быть всегда volatile" стало ложным.a5021 писал(а):Вот эта ваша "не должна", она работает только для вашего примера или для любых случаев?
Хотя бы с того, что в функции они мне нужны только один раз - прочитать и усреднить. При выходе эти регистры из стека уйдут, при повторном вызове фунций, снова попадут в стек и будут заполнены заново.ПростоНуб писал(а):с чего вы решили, что компилятор не закеширует значение всех четырех измерений в регистрах
Код: Выделить всё
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
//}
Что вы заладили с этим своим воидом. Не играет оно тут никакой роли.кстати, о проблемах: характерный источник проблем зачастую кроется именно в том, что написано не то, что подразумевается. и в данном контексте, как я уже говорил, лучший вариант интерфейса этой функции - указатель void*, демонстрирующий полное безразличие функции к данным по этому адресу.
Чепуху вы в очередной раз накидали. Пламенный ответ на вопрос, который вам никто не задавал.За неимением HAL-а, накидал простенький пример, иллюстрирующий обсуждаемый вопрос.
это может (???) произойти, как понимаю, уже после того, как злосчастная функция отработает, ведь она ничего, кроме записи в несколько регистров аппаратуты, не делает - верно? так зачем самой функции требовать volatile-буфер, если ей на это плевать? внутри этой функции никакой оптимизации нет и быть не может - там ДАННЫЕ не используются от слова вообще! нужно volatile снаружи функции или нет - вопрос другой, речь о параметрах функции!a5021 писал(а): Вы подготовили буфер к отправке, передали указатели в блок DMA, но к моменту, когда дело дойдет до реальной передачи, эта область памяти может быть использована компилятором по своему, а не вашему усмотрению.
А код, который вы со всем тщанием и трепетом собственноручно начертали можно выбрасывать? Так выбрасывает же. Выбрасывает в любом объеме, если сочтет бесполезным. Оптимизация называется.и, если честно, я как-то не очень понимаю: как может компилятор модифицировать область памяти, которую я выделил в программе, без моего ведома?! тут явно какой-то подвох...
На колу мочало...кстати, в MinGW GCC функция memset получает именно void*, потому и не ругается на любой буфер.
Сама функция тут вообще ни при делах, отчего я не собирался и не собираюсь обсуждать ее вовсе. Корень проблемы в том, как объявлены параметры этой функции. Это приводят к ложной генерации предупреждений там, где их быть не должно и молчаливого одобрения там, где открывается направление к совершению ошибочных действий. Это своего рода ловушка и весь кисляк в том, что ее почти никто не видит, даже если тыкать носом. Квалификация-с.А так кмк самой функции он кмк собаке пятая нога, то и применять его там никакого смысла нет.
то есть вы хотите сказать, что если я напишу static char buf[128]; то компилятор сможет его "соптимизировать", даже если я использую ссылку на него?! по-моему, это уже из области фантастики. тем более, если я этот самый buf получил из mallocVladislavS писал(а):Или даже вообще не выделяет память, если думает, что может обойтись регистром или константой.