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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> WinAVR и переменные
Guest_Serg79_*
сообщение Sep 27 2006, 07:21
Сообщение #1





Guests






Как разместить глобальную переменную по определенному адресу в памяти, при использовании WinAVR.
Например:
Код
/*
* Нужно разместить по адресу 0x0110
*/
char flag;

Как мне это сделать?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 27 2006, 08:30
Сообщение #2


Гуру
******

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



Цитата(Serg79 @ Sep 27 2006, 10:21) *
Как разместить глобальную переменную по определенному адресу в памяти, при использовании WinAVR.
Например:
Код
/*
* Нужно разместить по адресу 0x0110
*/
char flag;

Как мне это сделать?
Посмотреть в заголовочных файлах из комплекта компилятора как там по абсолютным адресам размещаются переменные портов, таймеров и другой периферии.


--------------------
На любой вопрос даю любой ответ
"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
Guest_Serg79_*
сообщение Sep 27 2006, 08:36
Сообщение #3





Guests






Народ, не ужели ни кто не знает как это сделать.
Для регистров это так:
Код
register uint8_t flag __asm__ ("r18");

а для памяти как?

Может кто знает как это в IAR-е делается?

Цитата(Сергей Борщ @ Sep 27 2006, 12:30) *
Цитата(Serg79 @ Sep 27 2006, 10:21) *

Как разместить глобальную переменную по определенному адресу в памяти, при использовании WinAVR.
Например:
Код
/*
* Нужно разместить по адресу 0x0110
*/
char flag;

Как мне это сделать?
Посмотреть в заголовочных файлах из комплекта компилятора как там по абсолютным адресам размещаются переменные портов, таймеров и другой периферии.

Походу так не прокатит, там вот что написанно:
Код
#define SREG      _SFR_IO8(0x3F)

хоть они и находяться в как бы в общей памяти но они все таки _SFR_.
Но я сейчас попробую.
Go to the top of the page
 
+Quote Post
Guest_Serg79_*
сообщение Sep 27 2006, 08:59
Сообщение #4





Guests






Цитата(Сергей Борщ @ Sep 27 2006, 12:30) *
Цитата(Serg79 @ Sep 27 2006, 10:21) *

Как разместить глобальную переменную по определенному адресу в памяти, при использовании WinAVR.
Например:
Код
/*
* Нужно разместить по адресу 0x0110
*/
char flag;

Как мне это сделать?
Посмотреть в заголовочных файлах из комплекта компилятора как там по абсолютным адресам размещаются переменные портов, таймеров и другой периферии.

Нет, так точно не прокатит. Вот что там есть:
Код
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define _MMIO_WORD(mem_addr) (*(volatile uint16_t *)(mem_addr))

#define _SFR_MEM8(mem_addr) _MMIO_BYTE(mem_addr)
#define _SFR_MEM16(mem_addr) _MMIO_WORD(mem_addr)

Данные макросы просто грамотно формируют указатель на соответствуюфий адрес. И данный диапозон адресов не используется компилятором под глобальные переменные.
А мне именно надо разместить переменную по адресу начинающемуся с 0x0100.
Go to the top of the page
 
+Quote Post
otrog
сообщение Sep 27 2006, 09:10
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 232
Регистрация: 22-02-06
Из: Воронеж
Пользователь №: 14 589



Для IAR-а делал так:
Код
#define r_mode  (* (char *) 0x8000) /* Declare a memory mapped I/O address*/

Попробуйте так:
Код
#define flag  (* (char *) 0x0110) /* Declare a memory mapped I/O address*/


--------------------
Истина рождается в спорах; но когда страсти кипят, истина испаряется.
Go to the top of the page
 
+Quote Post
Guest_Serg79_*
сообщение Sep 27 2006, 09:53
Сообщение #6





Guests






Цитата(otrog @ Sep 27 2006, 13:10) *
Для IAR-а делал так:
Код
#define r_mode  (* (char *) 0x8000) /* Declare a memory mapped I/O address*/

Попробуйте так:
Код
#define flag  (* (char *) 0x0110) /* Declare a memory mapped I/O address*/

Это то же самое что и
Код
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

Это просто тычек пальцем в память по определенному адресу, а откуда я знаю что компилятор разместил по этому адресу. Там может быть как глобальная так и статическая переменная, а может и ни чего не быть.

А мне надо имеено зарезервировать участок памяти определенного размера и по определенному адрессу. И что бы компилятор не использовал больше этот диапозон памяти под свои нужды.

Может кто знает как сдвинуть ".data" секцию вниз на пример на 8 байтов. Что бы скажем она уже начиналась не с адреса 0х0100 а с 0х0108.

Сообщение отредактировал Serg79 - Sep 27 2006, 09:54
Go to the top of the page
 
+Quote Post
Guest_Serg79_*
сообщение Sep 27 2006, 11:06
Сообщение #7





Guests






Представляете, в отстойном CodeVision это можно сделать:
Код
Global variables can be stored at specific SRAM locations at design-time using the @ operator.
Example:

/* the integer variable "a" is stored
   in SRAM at address 80h */
int a @0x80;

/* the structure "alfa" is stored
   in SRAM at address 90h */
struct x {
         int a;
         char c;
         } alfa @0x90;

А в WinAVR нельзя. Я в шоке. wacko.gif

Вы мне скажите, это хоть в IAR можно проделать?
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Sep 27 2006, 11:25
Сообщение #8


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Serg79 @ Sep 27 2006, 14:06) *
Вы мне скажите, это хоть в IAR можно проделать?

Легко!
Равно как и любую секцию расположить как угодно.
Go to the top of the page
 
+Quote Post
otrog
сообщение Sep 27 2006, 11:27
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 232
Регистрация: 22-02-06
Из: Воронеж
Пользователь №: 14 589



Цитата(Serg79 @ Sep 27 2006, 15:06) *
Вы мне скажите, это хоть в IAR можно проделать?

Вот так:
Код
__no_init int a @0x80;


--------------------
Истина рождается в спорах; но когда страсти кипят, истина испаряется.
Go to the top of the page
 
+Quote Post
Tiro
сообщение Sep 27 2006, 11:32
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768



Ну прочтите же, наконец, документацию!

excl.gif Перемещаем .data

WinAVR 20060421, avr-libc-user-manual-1.4.4.pdf

8.7.2 The .data Section
This section contains static data which was defined in your code. Things like the fol-
lowing would end up in .data:

Код
char err_str [] = "Your program has died a horrible death!";
struct point pt= { 1, 1 };


It is possible to tell the linker the SRAM address of the beginning of the .data section.
This is accomplished by adding -Wl,-Tdata,addr to the avr-gcc command
used to the link your program. Not that addr must be offset by adding 0x800000
the to real SRAM address so that the linker knows that the address is in the SRAM
memory space. Thus, if you want the .data section to start at 0x1100, pass 0x801100
at the address to the linker.

excl.gif Для того, чтобы привязать переменную к абсолютному адресу, можно назначить ей уникальное имя секции при помощи указания атрибута. Способ указания атрибутов переменных рассмотрен в gcc.pdf, раздел 5.32 Specifying Attributes of Variables.

Вот пример :

Код
int my_glob_var __attribute__ (( section ("my_glob_var") ));


excl.gif Как переместить секцию, написано в разделе 8.10.3 файла avr-libc-user-manual-1.4.4.pdf
Если линковка выполняется из avr-gcc, а не прямым вызовом avr-ld, то в командной строке (или в строке Makefile, где вызывается avr-gcc, надо написать -Wl,--section-start=.my_glob_var=0x801234
Go to the top of the page
 
+Quote Post
aesok
сообщение Sep 27 2006, 11:37
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(Serg79 @ Sep 27 2006, 11:21) *
Как разместить глобальную переменную по определенному адресу в памяти, при использовании WinAVR.


А зачем вам это нужно? Язык 'C ' как раз и был придуман для того чтобы избавить програмиста от ручного распределения переменных в памяти и переложить это на компилятор и линкер. Если вам нужно узнать по какому адресу компилятор расположил переменную - для этого сущесвуют указатели.

В WinAVR можно размещать переменые по абсолютным адресам:

1) Вы можете указать начало сегмента данных с адреса отличного от начала RAM, с помощью опции ликера -Tdata 0x8ххххх, и компилятор будет размещать переменые начиная с этого адреса.

2) Можоно создать свой сегмент, задать ему начальный адрес, и расположить ваши переменые в нем.


Анатолий.

Сообщение отредактировал aesok - Sep 27 2006, 11:39
Go to the top of the page
 
+Quote Post
Harvester
сообщение Sep 27 2006, 11:47
Сообщение #12


Местный
***

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



Цитата(Serg79 @ Sep 27 2006, 13:53) *
Цитата(otrog @ Sep 27 2006, 13:10) *

Для IAR-а делал так:
Код
#define r_mode  (* (char *) 0x8000) /* Declare a memory mapped I/O address*/

Попробуйте так:
Код
#define flag  (* (char *) 0x0110) /* Declare a memory mapped I/O address*/

Это то же самое что и
Код
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

...

А мне надо имеено зарезервировать участок памяти определенного размера и по определенному адрессу. И что бы компилятор не использовал больше этот диапозон памяти под свои нужды.

Может кто знает как сдвинуть ".data" секцию вниз на пример на 8 байтов. Что бы скажем она уже начиналась не с адреса 0х0100 а с 0х0108.

Вообще-то этим занимается не компилятор а компоновщик (linker). Соответственно все эти секции настраиваются в файле .xcl. А затем дефайном на зарезервированный участок.
Код
#define my_sect 0x....
....

char *ptr = (char *)my_sect;



Кстати, вот фрагмент такого файла (для нестандартной mega103):
Код
-D_..X_INTVEC_SIZE=60   /* 24 Interrupt vectors * 4 bytes each */
-D_..X_FLASH_TEND=FF    /* End of tiny flash memory */
-D_..X_FLASH_NEND=FFFF  /* End of near flash memory */
-D_..X_FLASH_END=1FFFF  /* End of flash memory */
/* Internal data memory */
-D_..X_SRAM_BASE=da00     /* Start of ram memory */
-D_..X_SRAM_TEND=daFF     /* End of tiny ram memory */

-D_..X_SRAM_END=dfff     /* End of ram memory */
/* Internal EEPROM */
-D_..X_EEPROM_END=FFF   /* End of eeprom memory */

За счет этих строк компилятор использует ОЗУ, начиная с адреса 0xda00. А вот строки из программы:
включаемый файл:
Код
//memory definition
#define mem_endP0In             0xc000
#define mem_endP0Out             0xc010

программа:
Код
volatile usb_ctrlrequest_t *usb_ctrl_req;
...
usb_ctrl_req=(usb_ctrlrequest_t *)mem_endP0In;

PS. На конкретные значения адресов не удивляйтесь, это не реальный контроллер, а ядро в ASIC-е


--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
Go to the top of the page
 
+Quote Post
defunct
сообщение Sep 28 2006, 23:50
Сообщение #13


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(aesok @ Sep 27 2006, 14:37) *
Язык 'C ' как раз и был придуман для того чтобы избавить програмиста от ручного распределения переменных в памяти и переложить это на компилятор и линкер.

Когда используется шина внешней памяти и по некоторым фиксированным адресам располагаются регистры внешних I/O устройств, то без ручного распределения просто нельзя обойтись...
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Sep 29 2006, 06:50
Сообщение #14


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(defunct @ Sep 29 2006, 02:50) *
Цитата(aesok @ Sep 27 2006, 14:37) *

Язык 'C ' как раз и был придуман для того чтобы избавить програмиста от ручного распределения переменных в памяти и переложить это на компилятор и линкер.

Когда используется шина внешней памяти и по некоторым фиксированным адресам располагаются регистры внешних I/O устройств, то без ручного распределения просто нельзя обойтись...

Ручного распределения действительно не избежать. То ли это будет назначение адресов в каком-нибудь выделенном сегменте, то ли определение переменных каждую в свой сегмент.
В любом случае линкеру (или программисту) работы прибавится.
Что же касается высокоуровневости языка С, то когда речь идёт о встроенных системах, то абсолютного абстрагирования от аппаратуры и её особенностей как правило не избежать. Об этом уже очень много писали.
Главное здесь, чтобы все подобные особенности были определены единожды (hal, bsp, называйте это как хотите) и доступны через заголовочные файлы. В этом случае никакого противоречия с С нет.
Go to the top of the page
 
+Quote Post
aesok
сообщение Sep 29 2006, 07:12
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(defunct @ Sep 29 2006, 03:50) *
Цитата(aesok @ Sep 27 2006, 14:37) *

Язык 'C ' как раз и был придуман для того чтобы избавить програмиста от ручного распределения переменных в памяти и переложить это на компилятор и линкер.

Когда используется шина внешней памяти и по некоторым фиксированным адресам располагаются регистры внешних I/O устройств, то без ручного распределения просто нельзя обойтись...


ДА, полностью с Вами согласен. Но вопрос был не про проты ввода/вывода, а про голобальную переменую в памяти. Порграмист в 'C' должен указывать сегмент в котором должна находиться переменая (data, EEPROM, ROM), а выбором ареса где будет нахадиться переменая в этом сегменте должен заниматься компилятор.


Анатолий.
Go to the top of the page
 
+Quote Post

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

 


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


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