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

 
 
 
Reply to this topicStart new topic
> Как инициализировать структуру в ЕЕПРОМ
Student2
сообщение Aug 5 2009, 18:57
Сообщение #1


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

Группа: Участник
Сообщений: 83
Регистрация: 4-08-09
Из: Болгария / София
Пользователь №: 51 737



Как можно инициализировать структуру в ЕЕПРОМ използуя полей (имена полей) внутри структуры?

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

__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
}; /* НЕ РАБОТАЕТ */

Конечно я могу установить ЕЕПРОМ не применяя полей структуры, но код будет хуже для поддержки.

Сообщение отредактировал Student2 - Aug 5 2009, 19:00
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Aug 6 2009, 04:49
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Или = { 2, 14, 8 }
или myEEPROM.status=2; myEEPROM.ID=14; myEEPROM.VER=8


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
xelax
сообщение Aug 6 2009, 06:05
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Я что-то не понимаю какая разница где расположена структура при её начальной инициализации.

мне кажется такого должно быть достаточно
Код
__root __eeprom header_t myEEPROM =
{
    .status = 2,
    .ID = 14,
    .VER = 8
};
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Aug 6 2009, 06:06
Сообщение #4


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



можно так

Код
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
Go to the top of the page
 
+Quote Post
Student2
сообщение Aug 6 2009, 09:37
Сообщение #5


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

Группа: Участник
Сообщений: 83
Регистрация: 4-08-09
Из: Болгария / София
Пользователь №: 51 737



Большое Спасибо - ответ был на 100% что искал!

Можно считать тему для закрытой - нечего можно добавить
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 6 2009, 20:34
Сообщение #6


Гуру
******

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



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


--------------------
На любой вопрос даю любой ответ
"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
xelax
сообщение Aug 7 2009, 05:50
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



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


В С++, есть конструкторы для таких вещей.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Aug 7 2009, 06:56
Сообщение #8


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



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


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 7 2009, 07:33
Сообщение #9


Гуру
******

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



Цитата(xelax @ Aug 7 2009, 08:50) *
В С++, есть конструкторы для таких вещей.
Там много чего есть. Я писал свой комментарий в том смысле, что если планируется потом этот код использовать и в С++ программах, то такой прием использовать нельзя. Ну или если этот код попадет в С++ программу и посыпятся ошибки компиляции, то чтобы было понятно, где их искать.


--------------------
На любой вопрос даю любой ответ
"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
xelax
сообщение Aug 7 2009, 08:27
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



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


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

Во вторых в ячейку он может и занесёт, но это справидливо только для eeprom. А если это структура в RAM, то числа сначала лягут во флэш, а потом скопируются в инициализационном коде в оперативку. Так что бесплатность условная.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Aug 7 2009, 13:15
Сообщение #11


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(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.
В этом смысле можно сказать, что добавление одной проинициализированной "по С" переменной бесплатно по коду (код копирования уже присутствует), а добавление "по С++" кроме самих инициализаторов добавляет коды операций загрузки этих инициализаторов в регистры и команды выгрузки их на нужное место.
Прикиньте, что будет при инициализации таблично-заданного развесистого меню в стиле с конструкторами.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
xelax
сообщение Aug 7 2009, 13:45
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035



Ну да всё правильно говорите.
Я и не утверждал что на плюсах код будет меньше. laughing.gif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 25th June 2025 - 13:02
Рейтинг@Mail.ru


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