• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

BLE SoC PHY6202

pvvx

Активный участник сообщества
Это необходимо чинить обязательно. Иначе возможны глупости при сравнении структур. В дополнительных байтах может оказаться всякий хлам.
 

cool2000

Member
После загрузки новой прошивки по OTA по адресам выше, оно и будет запускаться, но базовая останется
Может, чтобы не плодить прошивки, при старте грузить промежуточный загрузчик? Он смотрит, если есть корректный образ OTA в верхних адресах, то его переписывает, в противном случае запускает App.
 

cool2000

Member
Режим упаковки полей структур можно указать ключом -fpack-struct[=n] при компиляции.
Если нужно только упаковку менять, то можно проще:
C:
#pragma pack(1)
// Данные без выравнивания
...
// Возврат к упаковке по умолчанию.
#pragma pack()
 

pvvx

Активный участник сообщества
Чем отличается #pragma pack(1) от __attribute__((packed)) ?
При __attribute__((packed)) он uint32_t будет загружать побайтно, не смотря на выровненность адреса.
Почему то для других CPU этого не происходит - определяет что адрес выровнен...
 

pvvx

Активный участник сообщества
./SDK/components/ble/controller/ll_def.h:1280:1: warning: alignment 1 of 'struct <anonymous>' is less than 4 [-Wpacked-not-aligned]
на -fpack-struct
 

pvvx

Активный участник сообщества
Не обязательно. Зависит от архитектуры. Кажется M0 позволяет загружать невыровненные 4-х байтные слова.
Да пофиг на архитектуру - создавайте сами структуры только с выровненными адресами переменных. Это упрощает работу с ними в других системах. Но вот лишние байты в конце, если структура {uint32 x; uint8 b} тут всё нарушают. И вместо 5 байт выходит 8-мь.
 

cool2000

Member
Добавил невыровненную структуру и gcc сгенерировал побайтный код:
Код:
#pragma pack()
struct {
uint8_t  sz;
uint32_t val;
} aaa;
#pragma pack()

        aaa.sz = 1;
11020d6e:    2101          movs    r1, #1
11020d70:    4a0d          ldr    r2, [pc, #52]    @ (11020da8 <read_sensor+0x9c>)
11020d72:    7011          strb    r1, [r2, #0]
        aaa.val = _r32;
11020d74:    7053          strb    r3, [r2, #1]
11020d76:    1851          adds    r1, r2, r1
11020d78:    0a1a          lsrs    r2, r3, #8
11020d7a:    704a          strb    r2, [r1, #1]
11020d7c:    2200          movs    r2, #0
11020d7e:    0e1b          lsrs    r3, r3, #24
11020d80:    708a          strb    r2, [r1, #2]
11020d82:    70cb          strb    r3, [r1, #3]
Но везде пишут, что по скорости невыровненный доступ сильно проигрывает побайтному чтению, и кроме того в определённых случаях может сгененрировать hard fault
 

pvvx

Активный участник сообщества
-fpack-struct - text на 12 килобайт больше 🤪
Короче это опять "оптимизаторы" в gcc поигрались...
 

pvvx

Активный участник сообщества
Так делать не нужно:
struct {
uint8_t sz;
uint32_t val;
} aaa;

нужно так:
struct {
uint32_t val;
uint8_t sz;
} aaa;

И чтобы sizeof(aaa) был = 5.
Остальной маразм в gcc как нибудь обойду.
Это сделано, чтобы в случае массива из этих структур выравнивание не нарушалось.
Где тут не выровнено?
 

cool2000

Member

pvvx

Активный участник сообщества
Это сделано, чтобы в случае массива из этих структур выравнивание не нарушалось.
Я не Ардуинщик и не собираюсь составлять из нечетных по размеру структур массивы.
Гнать их всех погаными тряпками.. :)
Правда это уже началось - прогнозируют что ИИ в ближайшие 5 лет вычистит из "программистов" 99% на улицу собирать бутылки... О смерти любимых толпе языков программирования уже объявили.
Ныне соотношение бабок за строку кода у програмера (на либах и прочих API или группового кода) и ИИ уже 500:1 :p
 

pvvx

Активный участник сообщества
И при чем тут массивы?
При составлении массива берутся выровненные адреса для каждого элемента. Это никак не влияет на размер элемента.
Аналогично со структурами в структурах. Всегда начинаются с выровненного адреса, но размер может быть нечетным. Никому это не мешает.
И операция a = b со структурой не должна копировать лишние байты. И сравнение memcmp(a,b, sizeof(a)) отработает правильно. Иначе - нет.
 

pvvx

Активный участник сообщества
В общем приехали с gcc из за структурных программистов (коих точно вытеснит ИИ, т.к. всё их дело - это раздувание размера кода для понимания человеком, что нафиг не нужно машине) - Придется вручную считать размер структур и писать #define size_этой_стркутуры 5 .
 

pvvx

Активный участник сообщества
Какая тут логика?

struct {
uint8_t a;
}
Размер равен 1.

struct {
uint16_t a;
uint8_t b;
}
Размер равен 4.

struct {
uint32_t a;
uint8_t b;
}
Размер равен 8.
 

pvvx

Активный участник сообщества
C:
void test(void) {
    struct {
        uint32_t a;
        uint8_t b;
    }x1;
    struct {
        uint32_t a;
        uint8_t b;
    }x2;
    x1.a = 1;
    x1.b = 2;
    x2.a = 1;
    x2.b = 2;
    if (!memcmp(&x1, &x2, sizeof(x1)))
        return;
    LOG("BAG/BAD GCC! %u,%u != %u,%u\n", x1.a, x1.b, x2.a, x2.b);
}
Log:
Код:
BAG/BAD GCC! 1,2 != 1,2
Как жить?
 

pvvx

Активный участник сообщества
aaa[1].val окажется невыровненным.
Массивы значит?
C:
void test(void) {
    struct {
        uint32_t a;
        uint8_t b;
    }x[2];
    x[0].a = 1;
    x[0].b = 2;
    x[1].a = 1;
    x[1].b = 2;
    if (!memcmp(&x[0], &x[1], sizeof(x[0])))
        return;
    LOG("BAG/BAD GCC! %u,%u != %u,%u\n", x[0].a, x[0].b, x[1].a, x[1].b);
}
BAG/BAD GCC! 1,2 != 1,2
 

cool2000

Member
Массивы значит?
Ага ;)
C:
void test(void) {
    struct {
        uint32_t a;
        uint8_t b;
    }x[2];
    memset(x, 0, sizeof(x));
    x[0].a = 1;
    x[0].b = 2;
    x[1].a = 1;
    x[1].b = 2;
    if (!memcmp(&x[0], &x[1], sizeof(x[0])))
        return;
    LOG("BAG/BAD GCC! %u,%u != %u,%u\n", x[0].a, x[0].b, x[1].a, x[1].b);
}
Добавил -munaligned-access к ключам компиляции, gcc начал выдавать warning: target CPU does not support unaligned accesses.
 
Сверху Снизу