указатели в keil

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

указатели в keil

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

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

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

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

Re: указатели в keil

Сообщение BorisSPB »

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

Re: указатели в keil

Сообщение Sergi »

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

Re: указатели в keil

Сообщение VladislavS »

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

Re: указатели в keil

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

придется лепить его из отдельных байтов или прочитать сначала char и привести это значение к uint32_t.
Или просто в union их объединить.

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

Re: указатели в keil

Сообщение Reflector »

PS: Вообще, странно, что компилятор не выровнял адрес начала массива.

Он выровнял, просто в случае char это равнозначно отсутствию выравнивания. В С++ можно написать:

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

alignas(4) char number_tel_2[12] = "0000000000";

В С придется использовать всякие прагмы/атрибуты конкретного компилятора.
И да, почему-то никто не сказал, что проблемы с выравниванием есть только у Cortex-M0, с M3/M4 все будет работать, но чуть медленнее.
Последний раз редактировалось Reflector Вт сен 11, 2018 19:55:06, всего редактировалось 1 раз.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: указатели в keil

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

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

Re: указатели в keil

Сообщение afz »

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

Re: указатели в keil

Сообщение ARV »

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

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

Re: указатели в keil

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

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

Re: указатели в keil

Сообщение VladislavS »

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

Re: указатели в keil

Сообщение Reflector »

Если бы он выровнял, проблем не было бы.

Компилятор выровнял начало массива исходя из размера его элементов, в данном случае у нас массив байт, потому считай никакого выравнивания и нет. Но оно есть :) Можно было бы объявить массив как

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

int number_tel_2[12 / 4];

вот он выровнен по границам 4-х байт, правда строку ему не присвоишь.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: указатели в keil

Сообщение jcxz »

Указатель на uint32_t должен быть выровнен по 32-бита. Ядро Cortex-M не может считывать 32-битные значения с произвольного адреса. При попытке чтения uint32_t с нечетного адреса или адреса кратного 2 происходит прерывание HardFault.

Да ладно?!! Может стоить матчасть подучить прежде чем чушь нести? 8)

Добавлено after 2 minutes 28 seconds:
Ведь то, что он делает, и его код - большой большой секрет ! :)))

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

Re: указатели в keil

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

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

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

Re: указатели в keil

Сообщение VladislavS »

НУ почему сразу чушь ?
Потому что в том виде как оно сформулировано это ложное утверждение. Впрочем, тем кто это понимает цепляться к словам особого смысла нет.
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: указатели в keil

Сообщение 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 КБ) 1098 скачиваний
mem.png
(201.22 КБ) 1090 скачиваний
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: указатели в keil

Сообщение jcxz »

Впрочем, тем кто это понимает цепляться к словам особого смысла нет.

Вряд-ли это понимает автор темы, так как даже не указал какой у него МК.
Ser-B
Первый раз сказал Мяу!
Сообщения: 35
Зарегистрирован: Вт ноя 02, 2010 20:21:53

Re: указатели в keil

Сообщение 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;
}
Аватара пользователя
Мурик
Друг Кота
Сообщения: 3383
Зарегистрирован: Пн окт 11, 2010 19:00:08

Re: указатели в keil

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

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

Re: указатели в keil

Сообщение 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»