Во-во! Главная мысль там, что ажно
Это вообще не самые хилые дела ![]()
Во-во! Главная мысль там, что ажно
Это вообще не самые хилые дела ![]()
Вот здесь говорят о высших материях, а я, похоже, столкнулся с банальными граблями.
Есть такая структура, поля которой инициализируются в void setup():
struct
{
byte a;
byte b;
float c;
float d;
float e;
byte f;
int g;
bool h
} k1;
Я её пишу в EEPROM и читаю оттуда же. Указываю адрес структуры, адрес в EEPROM и sizeof(k1)…
Столкнулся вот с чем. При чтении поля выводятся в монитор порта с каким-то сдвигом! Танцевал я с этой проблемой до тех пор, пока не заменил типы byte и bool на int. Проблема, как бы, решилась.
Подскажите, пожалуйста, проблема все-таки решилась или “как бы”?
про выравнивание слышал чонить?
читай про #pragma pack(push, 1)
Не должно быть таких структур.
Если что, это и есть ответ на твой вопрос.
Про выравнивание слышал. Боюсь я его, но попробую. А чем не выравнивание, если типы содедржат чётное число байт?
Переделал структуру так:
struct
{
int a;
int b;
float c;
float d;
float e;
int f;
int g;
int h;
} k1;
Похоже, что стало работать нормально. Но проблема сдвига вернулась.
Обратился к совету @DetSimen : прочитал про
#pragma pack(push, 1)
Решил попробовать у себя. И тут выяснилось вот что. Скетч я заливаю через программатор USBasp из HEX - файла. Перед заливкой скетча EEPROM заполнена этой структурой. Но при чтении из EEPROM получается такой сдвиг, что во всех полях nan. А при очередных циклах записи - чтения всё работает нормально. Работаю с нулевым адресом EEPROM. Похоже, что структура меняет свой адрес после прошивки, а затем её адрес восстанавливается.
Нет, больше похоже, что руки и ноги у тебя растут из одного и того же места. Но так как информации недостаточно, гадать не буду.
Ну и что??? Попробовал #pragma pack(push, 1).
После прошивки через USBasp (через шнур не заливал) эта хрень осталась.
Сам ты, @DetSimen три дня не умывался. Здесь кроме @ЕвгенийП мало кто объяснит - в чем причина проблемы.
вот была тема,
может поможет
Сэр в курсе, что выравнивание может быть на границу одного, двух, четырех, восьми или шестнадцати байтов?
Я бы начал с того, что переупорядочил поля в структуре так, чтобы они в упакованном виде были выровнены на естественную границу. Ну не должно четырехбайтовое число начинаться по смещению 2!
И еще: если предполагается использование структуры для хранения либо передачи информации, в ней не должно быть полей типа int.
А как тогда в составе структуры передать, например, число ‘-3160’ ?
signed short не предлагать?
Чем он лучше int16_t ?
Ничем, это одно и тоже, только для int16_t нужно дополнительно подключатт <stint.h>
Это которые типы? byte? или bool?
Нет. Которые в #41.
Я цитировал ваше сообщение 40. Вы там писали про структуру, которую определили только в #41? Сильно
Если вернуться к сути - мало конкретики. Начните с того, что укажите, о каком контроллере речь? И далее покажите код, как вы сохраняете структуру и как читаете обратно. А то может дело не в выравнивании, а в банальной программной ошибке
Arduino - UNO. Код сейчас покажу, но перед этим напомню, что это получается после прошивки через USBasp. Затем при записи-чтении работает корректно.
Вызовы:
to_eeprom(&k1, 0, sizeof(k1)); // запись
from_eeprom(&k1, 0, sizeof(k1)); // чтение
Процедуры:
void to_eeprom(void *x, int adress, int razmer)
{
byte* ptr = (byte*) x;
int adr = adress;
for (int i = 0; i < razmer; i++)
{
EEPROM.update(adr, *(ptr + i));
adr++;
}
}
void from_eeprom(void *x, int adress, int razmer)
{
byte* ptr = (byte*) x;
int adr = adress;
for (int i = 0; i < razmer; i++)
{
*(ptr + i) = EEPROM.read(adr);
adr++;
}
}
чему равен?
Все логично же, уж сколько раз тут к этому подводят. Программа пишет и читает одинаково размещенную структуру. А предварительно сформированный дамп залитый через программатор сформирован с иными правилами упаковки. Или меняйте упаковку в программе, или меняйте формат предварительно подготовленного дампа.
Прошивать тоже надо уметь. Показывайте, как Вы это делаете и как готовите дамп для прошивки.