Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как инициализировать структуру в ЕЕПРОМ
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Student2
Как можно инициализировать структуру в ЕЕПРОМ използуя полей (имена полей) внутри структуры?

Сегодня из форума я узнал как сделать инициализацию ЕЕПРОМа с фиксированного адреса:

__root __eeprom uint8_t zast1[11] @ 0x2A = {0xFF, 0x44, 0x33, 0x11, 0x88, 0xAA, 0x77, 0x22, 0x44, 0xEE};


Но не могу понять как инициализировать структуру в ЕЕПРОМ ползуя имена полей. Например:

typedef struct
{
uint8_t status; /* STATUS */
uint8_t ID; /* ID */
uint16_t VER; /* VER */
} header_t;

Как можно инициализировать например поле status, ID, VER индивидуально? Я не хочу тратит програмный памяти для установки данны, хочу поставить данны директно в ЕЕПРОМ (EEP file).

__root __eeprom header_t myEEPROM = {
status = 2,
ID = 14,
VER = 8
}; /* НЕ РАБОТАЕТ */

Конечно я могу установить ЕЕПРОМ не применяя полей структуры, но код будет хуже для поддержки.
Dog Pawlowa
Или = { 2, 14, 8 }
или myEEPROM.status=2; myEEPROM.ID=14; myEEPROM.VER=8
xelax
Я что-то не понимаю какая разница где расположена структура при её начальной инициализации.

мне кажется такого должно быть достаточно
Код
__root __eeprom header_t myEEPROM =
{
    .status = 2,
    .ID = 14,
    .VER = 8
};
MALLOY2
можно так

Код
typedef struct
{
  char status; /* STATUS */
  char ID; /* ID */
  int VER; /* VER */
} header_t;


__root __eeprom header_t myEEPROM = {.status = 2, .ID = 14, .VER = 8};



P.S. пока инет тормозил уже ответили. smile.gif
Student2
Большое Спасибо - ответ был на 100% что искал!

Можно считать тему для закрытой - нечего можно добавить
Сергей Борщ
Цитата(Student2 @ Aug 6 2009, 12:37) *
Можно считать тему для закрытой - нечего можно добавить
Но такая инициализация не будет компилироваться в C++. Вот теперь можно закрывать.
xelax
Цитата(Сергей Борщ @ Aug 7 2009, 00:34) *
Но такая инициализация не будет компилироваться в C++. Вот теперь можно закрывать.


В С++, есть конструкторы для таких вещей.
ReAl
Цитата(xelax @ Aug 7 2009, 08:50) *
В С++, есть конструкторы для таких вещей.
Только С-99 инициализация с именами полей (и с индексами массивов int array[20] = { [10] = 5 }; ) - это операция времени компиляции, которая заносит значения в секцию инициализированных данных и "бесплатна" с точки зрения размера кода, а С++ - конструкторы - это операция времени выполнения и дополнительный код.
"А в остальном, прекрасная маркиза, всё хорошо, всё хо-ро-шо".
Сергей Борщ
Цитата(xelax @ Aug 7 2009, 08:50) *
В С++, есть конструкторы для таких вещей.
Там много чего есть. Я писал свой комментарий в том смысле, что если планируется потом этот код использовать и в С++ программах, то такой прием использовать нельзя. Ну или если этот код попадет в С++ программу и посыпятся ошибки компиляции, то чтобы было понятно, где их искать.
xelax
Цитата(ReAl @ Aug 7 2009, 10:56) *
Только С-99 инициализация с именами полей (и с индексами массивов int array[20] = { [10] = 5 }; ) - это операция времени компиляции, которая заносит значения в секцию инициализированных данных и "бесплатна" с точки зрения размера кода, а С++ - конструкторы - это операция времени выполнения и дополнительный код.
"А в остальном, прекрасная маркиза, всё хорошо, всё хо-ро-шо".


А конструктор не может на этапе компиляции проинлайниться? это во первых

Во вторых в ячейку он может и занесёт, но это справидливо только для eeprom. А если это структура в RAM, то числа сначала лягут во флэш, а потом скопируются в инициализационном коде в оперативку. Так что бесплатность условная.
ReAl
Цитата(xelax @ Aug 7 2009, 11:27) *
А конструктор не может на этапе компиляции проинлайниться? это во первых
Во вторых в ячейку он может и занесёт, но это справидливо только для eeprom. А если это структура в RAM, то числа сначала лягут во флэш, а потом скопируются в инициализационном коде в оперативку. Так что бесплатность условная.
Проинлайненый код - всё равно код, его размер не может быть даже равен размеру данных, которые он в себе несёт.
Код копирования образа .data во флеше присутствует один на все инициализаторы и делится на всех, практически можно пренебречь.
Итого для
Код
uint8_t  b = 5;
имеем
Код
    .byte 5
т.е. расход 1 батйт флеша на 1 байт проинициализированных данных (+ одна N-тая от общего кода копирования всей секции одним махом из флеша в ОЗУ)
А в случае самого заинлайненого конструктора
Код
    ldi  r16, 5
    sts  b, r16
итого шесть байт флеша на один байт проинициализированных данных.
Реальность может оказаться ещё хуже - даже проинлайненный конструктор ляжет в цепочку таких проинлайненных конструкторов в пределах единицы компиляции, но все вместе образуют подпрограмму, которая будет вызвана при запуске, а её адрес или её вызов будет помещён в соответствующую таблицу, которая ещё займёт место.
Например, так:
Код
#include <stdint.h>
class cpp_t {
public:
    cpp_t(uint8_t v8, uint32_t v32) : f8(v8), f32(v32) {}
private:
    uint8_t f8;
    uint32_t f32;
};

cpp_t cp_alone(3,0x12345678);
cpp_t cp[2] = { cpp_t(0,1), cpp_t(2,3) };


CODE
.text
.type _GLOBAL__I_c, @function
// Да, тут проинлайнились конструкторы для всех трёх объектов в одну цепочку
_GLOBAL__I_c:
/* prologue: function */
/* frame size = 0 */
ldi r24,lo8(3)
sts cp_alone,r24
ldi r24,lo8(305419896)
ldi r25,hi8(305419896)
ldi r26,hlo8(305419896)
ldi r27,hhi8(305419896)
sts cp_alone+1,r24
sts (cp_alone+1)+1,r25
sts (cp_alone+1)+2,r26
sts (cp_alone+1)+3,r27
sts cp,__zero_reg__
ldi r24,lo8(1)
ldi r25,hi8(1)
ldi r26,hlo8(1)
ldi r27,hhi8(1)
sts cp+1,r24
sts (cp+1)+1,r25
sts (cp+1)+2,r26
sts (cp+1)+3,r27
ldi r24,lo8(2)
sts cp+5,r24
ldi r24,lo8(3)
ldi r25,hi8(3)
ldi r26,hlo8(3)
ldi r27,hhi8(3)
sts cp+6,r24
sts (cp+6)+1,r25
sts (cp+6)+2,r26
sts (cp+6)+3,r27
/* epilogue start */
ret

.global __do_global_ctors
.section .ctors,"a",@progbits
// А это добавилась ссылка на объединённые конструкторы в таблицу
.word gs(_GLOBAL__I_c)

.section .bss
.type cp_alone, @object
.size cp_alone, 5
cp_alone:
.skip 5,0
.global cp
.global cp
.type cp, @object
.size cp, 10
cp:
.skip 10,0
Даже если бы компилятор уоптимизировал эти записи, загрущив один раз указательную пару и записывая по ней - всё равно в пределе расход при программной инициализации 4 байта флеша на байт проинициализированных даных, а при переносе образа - 1:1.
В этом смысле можно сказать, что добавление одной проинициализированной "по С" переменной бесплатно по коду (код копирования уже присутствует), а добавление "по С++" кроме самих инициализаторов добавляет коды операций загрузки этих инициализаторов в регистры и команды выгрузки их на нужное место.
Прикиньте, что будет при инициализации таблично-заданного развесистого меню в стиле с конструкторами.
xelax
Ну да всё правильно говорите.
Я и не утверждал что на плюсах код будет меньше. laughing.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.