указатели в keil

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вт ноя 02, 2010 20:21:53

Сообщение Ser-B »

char number_tel_2[ 12 ]="0000000000";
uint32_t *source_addr;

source_addr = (void*)number_tel_2;
temp = *source_addr; // <- здесь происходит зависание.

При выполнениии приведенных операций происходит зависание мк.
Подскажите что я делаю не так.
Реклама
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Сообщение BorisSPB »

Указатель на uint32_t должен быть выровнен по 32-бита. Ядро Cortex-M не может считывать 32-битные значения с произвольного адреса. При попытке чтения uint32_t с нечетного адреса или адреса кратного 2 происходит прерывание HardFault. Если нужно именно uint32_t придется лепить его из отдельных байтов или прочитать сначала char и привести это значение к uint32_t.
Реклама
Мучитель микросхем
Сообщения: 412
Зарегистрирован: Ср янв 04, 2012 11:57:40
Откуда: Алчевск

Сообщение Sergi »

А разве number_tel_2 не указывает на первый символ строки char number_tel_2[]?
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Указывает, но чтение производится 32-битное. По невыровненному адресу.
Реклама
Эиком - электронные компоненты и радиодетали
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

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

[uquote="BorisSPB",url="/forum/viewtopic.php?p=3454697#p3454697"]придется лепить его из отдельных байтов или прочитать сначала char и привести это значение к uint32_t.[/uquote] Или просто в union их объединить.

PS: Вообще, странно, что компилятор не выровнял адрес начала массива.
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Аlex",url="/forum/viewtopic.php?p=3454790#p3454790"]PS: Вообще, странно, что компилятор не выровнял адрес начала массива.[/uquote]
Он выровнял, просто в случае char это равнозначно отсутствию выравнивания. В С++ можно написать:

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

alignas(4) char number_tel_2[12] = "0000000000";
В С придется использовать всякие прагмы/атрибуты конкретного компилятора.
И да, почему-то никто не сказал, что проблемы с выравниванием есть только у Cortex-M0, с M3/M4 все будет работать, но чуть медленнее.
Последний раз редактировалось Reflector Вт сен 11, 2018 19:55:06, всего редактировалось 1 раз.
Реклама
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

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

Reflector писал(а):Он выровнял,
Если бы он выровнял, проблем не было бы.
Контактная информация:
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

Не пойму, только, зачем манипулировать четырьмя символами, как одним беззнаковым словом? там же явно наблюдаются цифры в ASCII. Какая может быть польза от манипуляций с кодом 0x30303030 ? Как число, оно не годится, как текст - тоже не очень...
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ну, наверное, сравнивать быстрее числа, чем символы - или 4 символа за раз, или 1...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

Сравнение строк через указатели на int32_t ? Хм... То ещё извращение :)))
Для этого есть стандартные библиотечные функции.
Но мы этого не узнаем. ТС, как и многие другие, - запустит пулю и сидит молча, подсматривает за темой. Ведь то, что он делает, и его код - большой большой секрет ! :)))
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Ну тогда давайте похоливарим, а то у нас нерешённые vs остались :
- win vs lin
- avr vs arm
- keil vs все
- swd vs uart
- etc...
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Аlex",url="/forum/viewtopic.php?p=3454806#p3454806"]Если бы он выровнял, проблем не было бы.[/uquote]
Компилятор выровнял начало массива исходя из размера его элементов, в данном случае у нас массив байт, потому считай никакого выравнивания и нет. Но оно есть :) Можно было бы объявить массив как

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

int number_tel_2[12 / 4];
вот он выровнен по границам 4-х байт, правда строку ему не присвоишь.
Мудрый кот
Сообщения: 1735
Зарегистрирован: Вт авг 15, 2017 10:51:13

Сообщение jcxz »

[uquote="BorisSPB",url="/forum/viewtopic.php?p=3454697#p3454697"]Указатель на uint32_t должен быть выровнен по 32-бита. Ядро Cortex-M не может считывать 32-битные значения с произвольного адреса. При попытке чтения uint32_t с нечетного адреса или адреса кратного 2 происходит прерывание HardFault.[/uquote]
Да ладно?!! Может стоить матчасть подучить прежде чем чушь нести? 8)

Добавлено after 2 minutes 28 seconds:
[uquote="Аlex",url="/forum/viewtopic.php?p=3454875#p3454875"]Ведь то, что он делает, и его код - большой большой секрет ! :)))[/uquote]
Дык - сопрёте же его гениальный код! :)))
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

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

НУ почему сразу чушь ?
Проблема действительно имеет место быть. Только не на всех ядрах.
Вот, в точности такая же проблема обсуждается - http://forum.cxem.net/index.php?/topic/ ... nt=3040527

Добавлено after 10 minutes 39 seconds:
VladislavS писал(а):Компилятор выровнял начало массива исходя из размера его элементов, в данном случае у нас массив байт, потому считай никакого выравнивания и нет. Но оно есть :)
Согласен. Он выровнял по байту. Для слов (2, 4 байта) уже, считай, что выравнивания нет :)
По этому и странно, что не положил массив начиная с выровненного по 4 байта поля. Хотя ... хз... хз... :dont_know:
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Аlex",url="/forum/viewtopic.php?p=3454915#p3454915"]НУ почему сразу чушь ?[/uquote]Потому что в том виде как оно сформулировано это ложное утверждение. Впрочем, тем кто это понимает цепляться к словам особого смысла нет.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Аlex писал(а):По этому и странно, что не положил массив начиная с выровненного по 4 байта поля. Хотя ... хз... хз... :dont_know:
Какие то древние ARMы имели доступ как памяти только выравненный по словам. На пикче слева, видна существенная потеря памяти, против современных, справа. Так что ничего странного.
Изображение
BorisSPB писал(а):Указатель на uint32_t должен быть выровнен по 32-бита. Ядро Cortex-M не может считывать 32-битные значения с произвольного адреса. При попытке чтения uint32_t с нечетного адреса или адреса кратного 2 происходит прерывание HardFault.
Cortex-M3. Оптимизация выключена.

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

	volatile uint32_t Buf=0x01020304;
	volatile uint32_t *pBuf=&Buf;
	Buf=*((uint32_t*)((uint8_t*)pBuf+1));
Код прошагал, исключения не произошло. Buf присвоилось 0x01020304, затем изменилось на 0x88010203.
Ниже дамп памяти. Красным подчернкнут адрес начала дампа, черным Buf после выполнения всего вышеуказанного кода, зеленым указатель.
Изображение
Ser-B писал(а): При выполнениии приведенных операций происходит зависание мк.
Надо в отладке поглядеть где висите.
ARV писал(а):ну, наверное, сравнивать быстрее числа, чем символы - или 4 символа за раз, или 1...
32разрядный МК должен работать быстрее с 32 разрядными числами, но душа просит все время 8битные переменные объявлять :), даже очень локальные флаги, которые скорее всего будут в регистре и само-собой займут его весь.
Вложения
dump.png
(10.03 КБ) 1105 скачиваний
mem.png
(201.22 КБ) 1098 скачиваний
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Мудрый кот
Сообщения: 1735
Зарегистрирован: Вт авг 15, 2017 10:51:13

Сообщение jcxz »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3454955#p3454955"]Впрочем, тем кто это понимает цепляться к словам особого смысла нет.[/uquote]
Вряд-ли это понимает автор темы, так как даже не указал какой у него МК.
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вт ноя 02, 2010 20:21:53

Сообщение Ser-B »

Никакого секрета нет.
Всего лишь хотел передать суть проблемы.
В М3 действительно все было норм, а М0 такая вот ерунда.
Задача записывать во флеш настройки скопом из всех массивов и считывать в массивы при включении мк.
Проблема исчезла при объявлении 32-разрядных массивов. Правда, появился дополнительный расход памяти.

uint32_t adr_sensor[QTY_TERM_SENSOR][8];
uint32_t number_tel[ QTY_NUMBER_TEL ];
float up_alarm_sensor[QTY_TERM_SENSOR];
float down_alarm_sensor[QTY_TERM_SENSOR];
float up_alarm_press_sensor[QTY_PRESS_SENSOR];
float down_alarm_press_sensor[QTY_PRESS_SENSOR];

void FLASH_ReadSettings(void) {
//Read settings
uint16_t i;
uint32_t *source_addr = (uint32_t *)MY_FLASH_PAGE_ADDR;
uint32_t *dest_addr;


dest_addr = (void *)adr_sensor;
for (i=0; i<(QTY_TERM_SENSOR*2); i++) {
*dest_addr = *(__IO uint32_t*)source_addr;
source_addr++;
dest_addr++;
}

dest_addr = (void *)mapping_sensor;
for (i=0; i<QTY_TERM_SENSOR; i++) {
*dest_addr = *(__IO uint32_t*)source_addr;
source_addr++;
dest_addr++;
}

dest_addr = (void *)up_alarm_sensor;
for (i=0; i<QTY_TERM_SENSOR; i++) {
*dest_addr = *(__IO uint32_t*)source_addr;
source_addr++;
dest_addr++;
}

dest_addr = (void *)down_alarm_sensor;
for (i=0; i<QTY_TERM_SENSOR; i++) {
*dest_addr = *(__IO uint32_t*)source_addr;
source_addr++;
dest_addr++;
}

dest_addr = (void *)up_alarm_press_sensor;
for (i=0; i<QTY_PRESS_SENSOR; i++) {
*dest_addr = *(__IO uint32_t*)source_addr;
source_addr++;
dest_addr++;
}

dest_addr = (void *)down_alarm_press_sensor;
for (i=0; i<QTY_PRESS_SENSOR; i++) {
*dest_addr = *(__IO uint32_t*)source_addr;
source_addr++;
dest_addr++;
}



dest_addr = (void *)number_tel;
for (i=0; i<QTY_NUMBER_TEL; i++) {
*dest_addr = *(__IO uint32_t*)source_addr;
source_addr++;
dest_addr++;
}



}
void FLASH_ProgramWord(uint32_t Address, uint32_t data){

//Write to Page
FLASH->CR |= FLASH_CR_PG; //Write 1 to PG (programming bit)
//*pPage = Temperature; //Write to flash page
*(__IO uint16_t*)(Address) = (uint16_t)data; //GET HARDFAULT HERE. CODE FROM ST
while ((FLASH->SR & FLASH_SR_BSY) != 0); //Wait until bus is not busy
if ((FLASH->SR & FLASH_SR_EOP) != 0){ //Check if flash is completed
FLASH->SR |= FLASH_SR_EOP; //Clear flag is flash is complete
}
data >>=16;
Address +=2;
*(__IO uint16_t*)(Address) = (uint16_t)data; //GET HARDFAULT HERE. CODE FROM ST
while ((FLASH->SR & FLASH_SR_BSY) != 0); //Wait until bus is not busy
if ((FLASH->SR & FLASH_SR_EOP) != 0){ //Check if flash is completed
FLASH->SR |= FLASH_SR_EOP; //Clear flag is flash is complete
}

FLASH->CR &= ~FLASH_CR_PG; //Clear prog bit to disable write to flash

}
void FLASH_WriteSettings(void) {
uint16_t i;
// Write settings
uint32_t *source_addr;
uint32_t *dest_addr = (uint32_t *) MY_FLASH_PAGE_ADDR;
// uint32_t temp=0;
//Clear Flags
FLASH->SR |= FLASH_SR_EOP; //Clear end of operation flag
FLASH->SR |= FLASH_SR_WRPRTERR; //Clear write protect error flag
FLASH->SR |= FLASH_SR_PGERR; //Clear programming error

//Unlock Flash
while ((FLASH->SR & FLASH_SR_BSY) != 0); //Wait until flash not busy
if ((FLASH->CR & FLASH_CR_LOCK) != 0){ //If flash is locked, do unlk seq.
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
}

//Erase Page before writing
FLASH->CR |= FLASH_CR_PER; //Enable flash page erase
FLASH->AR = MY_FLASH_PAGE_ADDR; //Set page to erase
FLASH->CR |= FLASH_CR_STRT; //Start erase
while ((FLASH->SR & FLASH_SR_BSY) != 0);//Wait until flash no busy
if ((FLASH->SR & FLASH_SR_EOP) != 0){ //If flash finished operation
FLASH->SR |= FLASH_SR_EOP; //Clear flag
}
FLASH->CR &= ~FLASH_CR_PER; //Disable page erase

source_addr = (void *)adr_sensor;
for (i=0; i<(QTY_TERM_SENSOR*2); i++) {
FLASH_ProgramWord((uint32_t)dest_addr, *source_addr);
source_addr++;
dest_addr++;
}

source_addr = (void *)mapping_sensor;
for (i=0; i<(QTY_TERM_SENSOR/4); i++) {
FLASH_ProgramWord((uint32_t)dest_addr, *source_addr);
source_addr++;
dest_addr++;
}

source_addr = (void *)up_alarm_sensor;
for (i=0; i<(QTY_TERM_SENSOR); i++) {
FLASH_ProgramWord((uint32_t)dest_addr, *source_addr);
source_addr++;
dest_addr++;
}

source_addr = (void *)down_alarm_sensor;
for (i=0; i<(QTY_TERM_SENSOR); i++) {
FLASH_ProgramWord((uint32_t)dest_addr, *source_addr);
source_addr++;
dest_addr++;
}

source_addr = (void *)up_alarm_press_sensor;
for (i=0; i<(QTY_PRESS_SENSOR); i++) {
FLASH_ProgramWord((uint32_t)dest_addr, *source_addr);
source_addr++;
dest_addr++;
}

source_addr = (void *)down_alarm_press_sensor;
for (i=0; i<(QTY_PRESS_SENSOR); i++) {
FLASH_ProgramWord((uint32_t)dest_addr, *source_addr);
source_addr++;
dest_addr++;
}


source_addr = (void *)number_tel;
for (i=0; i<QTY_NUMBER_TEL; i++) {
FLASH_ProgramWord((uint32_t)dest_addr, *source_addr);
source_addr++;
dest_addr++;
}



// FLASH_Lock();
FLASH->CR |= FLASH_CR_LOCK;
}
Друг Кота
Аватара пользователя
Сообщения: 3385
Зарегистрирован: Пн окт 11, 2010 19:00:08

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

Z_h_e писал(а):Код прошагал, исключения не произошло.
В M0 будет. http://purebasic.mybb.ru/viewtopic.php?id=564#p7599
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Сообщение BorisSPB »

Вообще-то, особенности есть:
3.3.5. Address alignment
An aligned access is an operation where a word-aligned address is used for a word, dual word, or multiple word access, or where a halfword-aligned address is used for a halfword access. Byte accesses are always aligned.

The Cortex-M4 processor supports unaligned access only for the following instructions:

LDR, LDRT

LDRH, LDRHT

LDRSH, LDRSHT

STR, STRT

STRH, STRHT

All other load and store instructions generate a UsageFault exception if they perform an unaligned access, and therefore their accesses must be address aligned.
http://infocenter.arm.com/help/index.js ... FAIGG.html
С приведением типов указателей надо быть аккуратнее...
Ответить

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