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

 
 
 
Reply to this topicStart new topic
> Как в кейле отключть zero-initialize для конкретной глобальной переменной?
Intel4004
сообщение Oct 20 2011, 01:57
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 48
Регистрация: 7-09-07
Из: Наб.Челны
Пользователь №: 30 364



Задача следующая: после ресета получить информацию из "прошлой жизни". Информация эта лежит в глобальных переменных.
Снять галочку NoInit в Options->Target (т.е. отключить zero-init для всей памяти) нельзя: используются сторонние библиотеки, а как они переживут такое - разбираться не хочется.
Т.е. надо что-то прямо противоположное __attribute__((zero_init))

Пока обошелся костылем - урезал в настройках размер памяти, и положил эти переменные по фиксированным адресам, про которые линкер не знает. Но это именно костыль. Некошерный. А как сделать красиво - не представляю...
Go to the top of the page
 
+Quote Post
sinc_func
сообщение Oct 20 2011, 05:03
Сообщение #2


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

Группа: Участник
Сообщений: 107
Регистрация: 29-05-10
Из: Пенза
Пользователь №: 57 619



Цитата(Intel4004 @ Oct 20 2011, 04:57) *
Задача следующая: после ресета получить информацию из "прошлой жизни". Информация эта лежит в глобальных переменных.
Снять галочку NoInit в Options->Target (т.е. отключить zero-init для всей памяти) нельзя: используются сторонние библиотеки, а как они переживут такое - разбираться не хочется.
Т.е. надо что-то прямо противоположное __attribute__((zero_init))

Пока обошелся костылем - урезал в настройках размер памяти, и положил эти переменные по фиксированным адресам, про которые линкер не знает. Но это именно костыль. Некошерный. А как сделать красиво - не представляю...


Вот из файла для линкера

LR_IROM1 0x00000000 0x00080000 { ; load region size_region
ER_IROM1 0x00000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x10000000 0x00008000 { ; RW data
.ANY (+RW +ZI)
}
}

+ZI управляет нулевой инициализацией

Сообщение отредактировал sinc_func - Oct 20 2011, 05:03
Go to the top of the page
 
+Quote Post
Harvester
сообщение Oct 20 2011, 05:19
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846



Цитата(Intel4004 @ Oct 20 2011, 05:57) *
Задача следующая: после ресета получить информацию из "прошлой жизни". Информация эта лежит в глобальных переменных.
Снять галочку NoInit в Options->Target (т.е. отключить zero-init для всей памяти) нельзя: используются сторонние библиотеки, а как они переживут такое - разбираться не хочется.
Т.е. надо что-то прямо противоположное __attribute__((zero_init))

Пока обошелся костылем - урезал в настройках размер памяти, и положил эти переменные по фиксированным адресам, про которые линкер не знает. Но это именно костыль. Некошерный. А как сделать красиво - не представляю...

В микрочиповском C30, который по-сути GCC, есть такие атрибуты, как
__attribute__((noload)) - выделить место под переменную, но не инициализировать ее
__attribute__((persistent)) - не инициализировать и не обнулять переменную при старте

Наверное и в Keil-е должно быть что-то похожее.

Альтернативный вариант - определить в файле линкера область памяти с атрибутом "без инициализации".

К сожалению, более конкретно не скажу - нет Keil-а под рукой


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
Intel4004
сообщение Oct 20 2011, 06:21
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 48
Регистрация: 7-09-07
Из: Наб.Челны
Пользователь №: 30 364



Цитата(sinc_func @ Oct 20 2011, 09:03) *
RW_IRAM1 0x10000000 0x00008000 { ; RW data
.ANY (+RW +ZI)
}
}

+ZI управляет нулевой инициализацией

Просто ZI убрать - не катит, остальную память чистить надо.
А вот так:
RW_IRAM1 0x10000000 0x00007f00 { ; RW data
.ANY (+RW +ZI)
}
RW_IRAM2 0x10007f00 0x00000100 { ; RW data no-zi
.ANY (+RW)
}
а потом принудительно в IRAM2 положить нужное - от того как сейчас почти не отличается...
В одном - в инклюдах: #define prev_state (*((PREV_STATE*)0x10007f00))
В другом - __attribute__((section("RW_IRAM2"))) PREV_STATE prev_state;
В обоих случаях правятся конфиги линкера, что чревато. Через пару лет забудешь, перетащишь эти исходники в другой проект - проблем не оберешься.

Цитата(Harvester @ Oct 20 2011, 09:19) *
В микрочиповском C30, который по-сути GCC, есть такие атрибуты, как
__attribute__((noload)) - выделить место под переменную, но не инициализировать ее
__attribute__((persistent)) - не инициализировать и не обнулять переменную при старте
Наверное и в Keil-е должно быть что-то похожее.

warning: #1207-D: attribute "persistent" ignored
warning: #1207-D: attribute "noload" ignored
Если и есть - я не нашел. Полдня в документации копался.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Oct 20 2011, 09:11
Сообщение #5


Гуру
******

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



Создайте секцию с атрибутом UNINIT:
Код
DBGINFO 0x10000000 UNINIT 0x00000080
{
    ...
}

Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 00:05
Рейтинг@Mail.ru


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