Отговори на тема  [ 13 мнения ] 
KEIL C51 масив - поставяне на определено в CODE място ? 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение KEIL C51 масив - поставяне на определено в CODE място ?
Имам един масив, да кажем Table, с предварително зададени стойности, искам да го поставя на определено във FLASH-а място. При други компилатори обикновено това се прави с ORG, в KEIL този директив важи само при ASM файловете. В Help-а има описана една ключова думичка _at_, която ми позволява да поставя променлива на определен адрес:

KEIL Help for _at_ написа:
struct link list idata _at_ 0x40; /* list at idata 0x40 */
char xdata text[256] _at_ 0xE000; /* array at xdata 0xE000 */
int xdata i1 _at_ 0x8000; /* int at xdata 0x8000 */
volatile char xdata IO _at_ 0xFFE8; /* xdata I/O port at 0xFFE8 */


Проблема е, че не ми дава да инициализирам стойностите на масив:
Код:
code const unsigned char Table[4] = {0,1,2,3}; // където и да сложа _at_ не се компилира


Някой знае ли как се прави този трик ?


Чет Фев 15, 2007 7:17 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение 
Ами там в документацията си пише:

Цитат:
The following restrictions apply to absolute variable location:
1. Absolute variables cannot be initialized.


Пет Фев 16, 2007 12:37 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Е това не е ли супер простотия ? :evil:


Пет Фев 16, 2007 1:02 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Фев 24, 2005 11:41 pm
Мнения: 1049
Местоположение: Pz
Мнение 
Пробвай това:
Код:
code const unsigned char Table[] _at_ 0x23;
code const unsigned char Table[] = "Hello World";

Не дава грешка, но не съм сигурен, дали го слага на указания адрес.


Пет Фев 16, 2007 1:13 am
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Пон Апр 03, 2006 9:00 am
Мнения: 39
Мнение 
Keil-a няма ли нещо като #pragma директиви?


Пет Фев 16, 2007 11:18 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Верно, компилира се, обаче KEIL компилатора пак хвърля масива в общия const space. Явно няма начин да стане това, ще мисля друга алтернатива :?

Edit: Има си прагма, опитвам с #pragma ASM/ENDASM да поставя масив писан на ASM, обаче компилатора си има някаква странна идея да не слуша в кой адрес искам да е даден сегмент, примерно:
Код:
#pragma ASM
ORG 0xF000 // Change location to 0xF000
DB 1
DB 2
DB 3
ORG 0x0000 // Chagne back location
#pragma ENDASM

Това прави кода ми от 16K CODE в 76К 8O


Пет Фев 16, 2007 11:19 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение 
Predator_MF написа:
Е това не е ли супер простотия ? :evil:


Ами не съм много сигурен защо ти трябва да е на точно определено място. :)
Иначе да, отнесено към променливи, закотвени на определен адрес във флаша, липсата на инициализация малко обезсмисля целия процес. :) Можеш да го направиш с някакъв инициализационен код и еднократна инициализация, нещо такова:

Код:
code char testarr[203] _at_ 0x1234;

main()
{
  if ((testarr[0] != 0x11) || (testarr[1] != 0x22) || (testarr[2] != 0x33))
  {
     InitArray();
     testarr[0] = 0x11;
     testarr[1] = 0x22;
     testarr[2] = 0x33;
  }
}



Пет Фев 16, 2007 11:59 am
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Вто Юли 18, 2006 12:53 pm
Мнения: 22
Местоположение: Липщат
Мнение Един груб подход
Един груб подход:

Отдели обекта в отделен файл (LOL.c)
иииииииииииии:

static const byte code GlobSWVersion = SW_VERSION;

Tab "LX51 Locate":
?CO?LOL(C:0x1FFF)


...
001FF5H 001FFEH 00000AH --- --- **GAP**
001FFFH 001FFFH 000001H BYTE UNIT CONST ?CO?LOL


Пет Фев 16, 2007 12:01 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Реконструктор написа:
Ами не съм много сигурен защо ти трябва да е на точно определено място. :)

Иначе да, отнесено към променливи, закотвени на определен адрес във флаша, липсата на инициализация малко обезсмисля целия процес. :) Можеш да го направиш с някакъв инициализационен код и еднократна инициализация, нещо такова:

Код:
code char testarr[203] _at_ 0x1234;

main()
{
  if ((testarr[0] != 0x11) || (testarr[1] != 0x22) || (testarr[2] != 0x33))
  {
     InitArray();
     testarr[0] = 0x11;
     testarr[1] = 0x22;
     testarr[2] = 0x33;
  }
}


Това няма да работи, защото масива е във FLASH-a и писането по него става по малко по-различен начин (за Cygnal става въпрос), иначе съм си го мислил като вариант при първата инициализация да има такова писане (или някаква допълнителна програма с която да "калибрирам" устройството). Тая думичка _at_ ми се вижда леко безмислена, след като мога да дефинирам pointer, който да сочи към определен адрес във флаша:
Код:
const code unsigned char* P_Table = 0xF000;

Масива ми трябва да стои на определен във флаша блок (флаша е разделен на 128 блока по 512 байта), който да ползвам като EEPROM например (в тоя проц EEPROM няма) и простата идея е да подкарам устройството с някакви предварително зададени стойности в EEPROM-a.

@Noble, мерси за идеята, ще пробвам :)


Пет Фев 16, 2007 12:26 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Noble, имам да черпя, малко е "дървено" наистина, обаче работи :)


Пет Фев 16, 2007 12:38 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Вто Юли 18, 2006 12:53 pm
Мнения: 22
Местоположение: Липщат
Мнение :-)
:-)

И аз го изгледах на кестерме това като ми се наложи да го направя преди време ...
А дано някой излезе с елегантно предложение ...


Пет Фев 16, 2007 12:41 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Пон Апр 03, 2006 9:00 am
Мнения: 39
Мнение drugo reshenie
Another method of referencing explicit memory locations is to declare the variables in a stand-alone C module and use the linker location directives to locate them at an absolute memory address.

In the following example, the alarm_control structure is defined containing the variables to locate.

.
.
.
struct alarm_st {
unsigned int alarm_number;
unsigned char enable flag;
unsigned int time_delay;
unsigned char status;
};

xdata struct alarm_st alarm_control;
.
.
.

The C51 Compiler generates an object file for the above source (ALMCTRL.C) and includes a segment for variables in the xdata memory area. Since alarm_control is the only variable declared in this module, it is the only variable in the xdata segment. The name of the segment is ?XD?ALMCTRL.

The linker can locate a segment at any address. The following examples show how to locate the ?XD?ALMCTRL segment starting at offset 0x2000 in the xdata memory area.

For the BL51 Linker...

BL51 ... almctrl.obj XDATA(?XD?ALMCTRL(2000h)) ...

For the LX51 Linker...

LX51 ... almctrl.obj SEGMENTS(?XD?ALMCTRL(X:0x2000)) ...

You may also locate segments in the other memory areas like code, xdata, pdata, idata, and data


Съб Фев 17, 2007 12:05 pm
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Пет Фев 17, 2006 9:17 am
Мнения: 765
Местоположение: Стара Загора
Мнение 
http://onembedding.com/tools/keil/artic ... icit_addr/


Пон Фев 19, 2007 1:47 pm
Профил ICQ
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 13 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 1 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни