реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Переменная по адресу не кратному 4 байт.
maxntf
сообщение Sep 12 2018, 15:29
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 107
Регистрация: 13-05-09
Пользователь №: 49 008



Всем привет, наткнулся на такой баг - объявил буфер в глобальных переменных.
Передаю его адрес в аргументе функции. И когда обращаюсь в функции к этой переменной через указатель сразу вылетаю в HardFault_Handler.
Пол дня парился, и в конце концов выяснил, что линковщик расположил ее по адресу не кратному 4.
Проверил, действительно если передать в функцию указатель не кратный 4, то при чтении по этому адресу вылетаем в HardFault_Handler.
И теперь не могу добиться, чтоб этот буфер разместился по корректному адресу. Добавляю перед ним или после него новые переменные, адреса смещаются, и у него все равно адрес не корректный.
Что делать?


P.S
Keil V5.23.0.0

Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 12 2018, 15:33
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(maxntf @ Sep 12 2018, 18:29) *
линковщик расположил ее по адресу не кратному 4


Сейчас принято делать так: http://www.keil.com/support/man/docs/armcc...59124981436.htm
но раньше делали так: http://www.keil.com/support/man/docs/armcc...59124966304.htm

И укажите версию компилятора.
Keil умеет работать с разными компиляторами, в комплекте к нему нынче идут ДВА встроенных РАЗНЫХ, и даже можно подключить внешний (GNU например)


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 12 2018, 15:35
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (maxntf @ Sep 12 2018, 18:29) *
Что делать?

1) Уменьшить картинку, чтобы страница форума не расползалась.
2) Показать объявление этого буфера.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Sep 13 2018, 08:10
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Скопировать значение в выравненную переменную с помощью memcpy. Вызвать функцию с этой локальной переменной. (опционально)Скопировать значение назад. Это и есть пуленепробиваемое решение которое работает везде, независимо от типов и версий компиляторов и языка.
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 13 2018, 08:21
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Kabdim @ Sep 13 2018, 11:10) *
Скопировать значение в выравненную переменную с помощью memcpy. Вызвать функцию с этой локальной переменной. (опционально)Скопировать значение назад. Это и есть пуленепробиваемое решение которое работает везде, независимо от типов и версий компиляторов и языка.

Ваш совет - один из лидеров среди самых вредных и опасных советов cranky.gif
Кстати, memcpy - очень коварный костыль!

Любой компилятор умеет "говорить" о том, какой он и даже "назвать" свою версию.
Ничто не мешает использовать эту информацию в своем коде для учета особенностей разных компиляторов, если есть нужда в поддержки разных компиляторов.

Пример реально пуленепробиваемого решения:
Код
// Arm Compiler v5
#if   defined ( __CC_ARM )

    #pragma import(__use_no_heap)
    #pragma import(__ARM_use_no_argv)
    #pragma import(__use_two_region_memory)

// Arm Compiler v6
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)

    __asm(".global __use_no_heap \n\t");
    __asm(".global __ARM_use_no_argv \n\t");
    __asm(".global __use_two_region_memory \n\t");

#endif


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
maxntf
сообщение Sep 13 2018, 08:55
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 107
Регистрация: 13-05-09
Пользователь №: 49 008



Цитата(Forger @ Sep 12 2018, 18:33) *
Сейчас принято делать так: http://www.keil.com/support/man/docs/armcc...59124981436.htm

Спасибо, понял в чем тут дело.
Просто раньше работал только с 8 битными МК, там таких проблем нет.

А у меня получилось, что буфер char - выравнивание у него по одному байту (без атрибута, начинаться может с любого адреса), а в качестве аргумента функции я передаю указатель на этот буфер с приведением типа до uint32.

Сообщение отредактировал maxntf - Sep 13 2018, 09:00
Go to the top of the page
 
+Quote Post
ViKo
сообщение Sep 13 2018, 09:01
Сообщение #7


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



union спасает выравнивание при любых компиляторах.
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 13 2018, 09:03
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Сергей Борщ @ Sep 12 2018, 18:35) *
2) Показать объявление этого буфера.

+1.
Сначала надо не костылями подпирать, а разобраться, в чём первопричина проблемы.

Цитата(maxntf @ Sep 13 2018, 11:55) *
А у меня получилось, что буфер char - выравнивание у него по одному байту (без атрибута, начинаться может с любого адреса), а в качестве аргумента функции я передаю указатель на этот буфер с приведением типа до uint32.

Это ужасно. Костыль в виде aligned вылечит, но ужас никуда не денется.
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 13 2018, 10:17
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(scifi @ Sep 13 2018, 12:03) *
Костыль в виде aligned вылечит, но ужас никуда не денется.

Ну-ну, попробуйте объявить массив для стека какой-нить задачи RTOS, НЕ применив к нему обязательный "костыль" aligned. ...


"Ужас" убирается объявлением вместо банальных байтовых массивов с разношерстными данными ("протокольные" дела) объявлением полноценных структур с полями нужных размеров и названий, даже с применением union, где это нужно.
Чтобы структура была одинакового размера на любых компиляторах, нужен атрибут packed. Это - норма.
После чего в соотв. функцию передается ссылка (&) на структуру (или указатель, если нельзя писать на плюсах).
В этом случае правильный доступ к полям структуры станет головной болью компилятора, а не кодера.

Вот пример обяявления такой структуры (не самый лучший пример, но тем не менее):
Код
struct __PACKED Frame
{
    uint8_t start;
    uint8_t command;
    uint8_t dataSize;
    union
    {
        uint8_t payload[COMMUNICATION_MAX_FRAME_DATA_SIZE_IN_BYTES];
        MasterToSlave masterToSlave;
        SlaveToMaster slaveToMaster;
    } data;
    struct
    {
        union
        {
            struct
            {
                uint8_t low;
                uint8_t high;
            };
            uint16_t value;
        };
    } crc16;
};

// SlaveToMaster  и SlaveToMaster  - структуры одинакового размера, но с разными полями


ps. из-за необходимости применения телепатии к стартовому посту эта тема рискует перейти в очередной холивар :D


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Sep 13 2018, 14:55
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(Forger @ Sep 13 2018, 11:21) *
Ваш совет - один из лидеров среди самых вредных и опасных советов cranky.gif
Кстати, memcpy - очень коварный костыль!

Пруфов, я так понимаю, дождаться нереально?
Цитата(Forger @ Sep 13 2018, 11:21) *
Пример реально пуленепробиваемого решения:

Гы! biggrin.gif
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 13 2018, 15:15
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Kabdim @ Sep 13 2018, 17:55) *
Пруфов, я так понимаю, дождаться нереально?

Вы правы - это бесполезный пруф из разряда: почему нужно мыть руки перед едой или чистить зубы. Это знают даже дети biggrin.gif
Во многих уважающих себя конторах это "наследие" вообще давно запрещено к применению.
Хотя в примитивном коде, который ни за что не отвечает или служит чисто образовательным целям (ардуины), memcpy в целом беды не несет, разве что кроме впустую потраченных нервов и времени smile3046.gif


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 14 2018, 06:40
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Forger @ Sep 13 2018, 13:17) *
Ну-ну, попробуйте объявить массив для стека какой-нить задачи RTOS, НЕ применив к нему обязательный "костыль" aligned. ...

Скажем, lwip делает это легко и непринуждённо. Нужно выравнивать по 4 байта? Прибавь к размеру массива 3 байта, а указатель отрихтуй до ровного.
Go to the top of the page
 
+Quote Post
Forger
сообщение Sep 14 2018, 07:47
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(scifi @ Sep 14 2018, 09:40) *
Скажем, lwip делает это легко и непринуждённо.

Не пойму, при чем тут lwip?
Ядро ARM требуют выравнивание стеков по границе 8 байт, иначе вылетаем в HF.

Не вижу никакой сложности использовать встроенное расширение компилятора, которое полностью устраняет эту "проблему".
Тем более компилятор v6 от ARM практически полностью поддерживает расширения GCC (в отличие от v5, который в целом устарел и поэтому лишь частично умеет это делать).

Цитата
Нужно выравнивать по 4 байта? Прибавь к размеру массива 3 байта, а указатель отрихтуй до ровного.

Соревнуетесь с Kabdim по вредности "советов"? wink.gif


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Sep 14 2018, 08:56
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(Forger @ Sep 13 2018, 18:15) *
Вы правы - это бесполезный пруф из разряда: почему нужно мыть руки перед едой или чистить зубы. Это знают даже дети biggrin.gif

Потому что пруфы для мытья рук есть и если не заниматься демагогией их несложно найти.
Цитата(Forger @ Sep 13 2018, 18:15) *
Во многих уважающих себя конторах это "наследие" вообще давно запрещено к применению.

И видимо что бы запретить совсем уж всю идею копирования памяти в другое место они придумали memcpy_s... biggrin.gif
Цитата(Forger @ Sep 13 2018, 18:15) *
Хотя в примитивном коде, который ни за что не отвечает или служит чисто образовательным целям (ардуины), memcpy в целом беды не несет, разве что кроме впустую потраченных нервов и времени smile3046.gif

Ну и к чему эти намеки, если вдруг вы не догадывались, то с Ардуиной я никогда не работал и к образованию кого-либо отношения не имею. Вы мешаете в один чан два разных применения. С буферами переменной длинны где для использования memcpy нужно много проверок и всё зло от того что индусы о ни забывают, а их отсутствие не обеспечивает падение сразу. А с другой стороны копирование переменной фиксированной длинны, где единственная задача убедится что на входе есть данные нужного размера. Если вы тратите на второй вариант использования memcpy нервы и время, могу только посочувствовать.
Цитата(Forger @ Sep 14 2018, 10:47) *
Соревнуетесь с Kabdim по вредности "советов"? wink.gif

Не переживайте, в этом вопросе вы непревзойденный идеал. biggrin.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 14 2018, 09:04
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Kabdim @ Sep 14 2018, 11:56) *
Потому что пруфы для мытья рук есть и если не заниматься демагогией их несложно найти.

Пруф. Нельзя вызывать memcpy абы как.

Ну и обратный пруф - memcpy спасает мир biggrin.gif
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th April 2024 - 20:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.015 секунд с 7
ELECTRONIX ©2004-2016