Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Массив констант разместить во flash памяти.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
Dan_Dima
Необходимо массив констант разместить во flash памяти. Как это сделать в C (компилятор IAR). Массив задаеться изначально и потом не меняеться.
jorikdima
const int arr[10]
Dan_Dima
Цитата(jorikdima @ Feb 14 2007, 22:44) *
const int arr[10]


Притаком объявлении массив размещаеться в RAM а не во flash, а надо именно во flash.
rezident
Цитата(Dan_Dima @ Feb 15 2007, 01:13) *
Цитата(jorikdima @ Feb 14 2007, 22:44) *

const int arr[10]


Притаком объявлении массив размещаеться в RAM а не во flash, а надо именно во flash.

Для IAR все верно указано. Квалификтор const указывает, что массив располагается в сегменте констант, а сегмент констант по-умолчанию располагается во Flash. См. сами xcl-файл. Например, в lnk430F149.xcl указано
Цитата
// Program and non-volatile segments (FLASH)
// =========================================
//
// segment address range usage
// ------- ------------- --------------------------
// INFO 1000-10FF Information memory
// CSTART 1100-FFDF cstartup program code
// CODE 1100-FFDF Program code
// DATA16_C 1100-FFDF Constant "const" variables AND String literals
// DATA16_ID 1100-FFDF Initializers for DATA16_I
// DIFUNCT 1100-FFDF Dynamic initialization vector used by C++
// CHECKSUM 1100-FFDF The linker places the checksum byte(s) in this segment,
// when the -J linker command line option is used.
//
// INTVEC FFE0-FFFF Interrupt vectors
//
// NOTE:
// It is not possible to pack the CSTART segment by using the XLINK -P option
// Special function registers and peripheral modules occupy addresses 0-01FFh
// Be sure to use end values for the defined addresses
//*****************************************************************
Alex11
Есть еще прямой модификатор __flash. Я только не помню точно, есть ли он для MSP430.
rezident
Цитата(Alex11 @ Feb 15 2007, 03:19) *
Есть еще прямой модификатор __flash. Я только не помню точно, есть ли он для MSP430.

В IAR EW430 нету. Вы видимо с IAR EWAVR перепутали.
VAI
Цитата(Dan_Dima @ Feb 15 2007, 00:13) *
Цитата(jorikdima @ Feb 14 2007, 22:44) *

const int arr[10]


Притаком объявлении массив размещаеться в RAM а не во flash, а надо именно во flash.

Прежде, чем так утверждать, включите генерацию листинга и посмотрите.
Для ИАРа
Код
static int sizeofreg( int reg )
{
static const int s_ofreg[] = { 0, 1, 1, 2, 0, 0, 2, 2 };

  return( s_ofreg[reg >> 3] );
}

Код
     20          static int sizeofreg( int reg )
     21          {

   \                                 In segment DATA16_C, align 2, align-sorted
     22          static const int s_ofreg[] = { 0, 1, 1, 2, 0, 0, 2, 2 };
   \                     ??s_ofreg:
   \   000000   000001000100 DC16 0, 1, 1, 2, 0, 0, 2, 2
   \            020000000000
   \            02000200    
     23          
     24            return( s_ofreg[reg >> 3] );
     25          }
     26
rvk
const word mnday @0xС600 = {....}
размещает по заранее известному адресу
jorikdima
вы все таки наверно хотели спрость/сказать следующеее, как сделать так чтоб массив размещался во флеш и НЕ ПЕРЕПИСЫВАЛСЯ в РАМ после инициализации, то есть и читался потом также из флэшь. Да?
VAI
да не переписывается он в РАМ и читается из флэшь, если внутри функции объявляете, то добавьте static.
Код
   \                                 In segment CODE, align 2
     20          int sizeofreg( int reg )
   \                     sizeofreg:
     21          {
     22          static const int s_ofreg[] = { 0, 1, 1, 2, 0, 0, 2, 2 };
     23          
     24            return( s_ofreg[reg >> 3] );
   \   000000   0C11         RRA.W   R12
   \   000002   0C11         RRA.W   R12
   \   000004   0C11         RRA.W   R12
   \   000006   0C5C         RLA.W   R12
   \   000008   1C4C....     MOV.W   ??s_ofreg(R12), R12
   \   00000C   3041         RET
     25          }

   \                                 In segment DATA16_C, align 2, align-sorted
   \                     ??s_ofreg:
   \   000000   000001000100 DC16 0, 1, 1, 2, 0, 0, 2, 2
   \            020000000000
   \            02000200    
     26

Покажите мне, где он переписывается в РАМ?
Никакой дополнительной инициализации не происходит. Все верно.
Dan_Dima
Все спасибо за помощь. Все правильно мой глюк smile.gif массив у меня изначально записывался во flash меня смутило что через дебагер видно что он массив при работе копирунт в RAM. В звязи с этим вопрос как от этого избавиться. Массив продекларирован в глобальной области
rezident
Цитата(Dan_Dima @ Feb 15 2007, 17:31) *
через дебагер видно что он массив при работе копирунт в RAM. В звязи с этим вопрос как от этого избавиться.

Приведите исходный код для изучения такого странного поведения компилятора. Вы printf/sprintf для работы с этим массивом случайно не используете?
Dan_Dima
Цитата(rezident @ Feb 15 2007, 15:42) *
Цитата(Dan_Dima @ Feb 15 2007, 17:31) *

через дебагер видно что он массив при работе копирунт в RAM. В звязи с этим вопрос как от этого избавиться.

Приведите исходный код для изучения такого странного поведения компилятора. Вы printf/sprintf для работы с этим массивом случайно не используете?


const unsigned char addres[128]= {0x01,0x02,0x5a,0x51,0x52,0x53,0x54,0x56,0x57,0x58, //1
0x59,0x4d,0x50,0x5b,0x03,0x0c,0x0d,0x0e,0x0f,0x33, //2
0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D, //3
0x3e,0x4a,0x41,0x42,0x43,0x44,0x45,0x49,0x46,0x47, //4
0x48,0x4c,0x40,0x4b,0x70,0x71,0x72,0x60,0x6a,0x6b, //5
0x6c,0x6d,0x6e,0x6f,0x74,6,7,8,9,10, //6
1,2,3,4,5,6,7,8,9,10, //7
1,2,3,4,5,6,7,8,9,10, //8
1,2,3,4,5,6,7,8,9,10, //9
1,2,3,4,5,6,7,8,9,10, //10
1,2,3,4,5,6,7,8,9,10, //11
1,2,3,4,5,6,7,8,9,10, //12
1,2,3,4,5,6,7,8}; //13

const unsigned char byte[128]= {0x40,0x00,0x85,0x01,0x00,0x00,0x00,0x03,0x00,0x00, //1
0x00,0x00,0x10,0x00,0x00,0x14,0x28,0x42,0x56,0x0a, //2
0x03,0x03,0x00,0xff,0xff,0x85,0x34,0xa2,0x38,0x98, //3
0x00,0x84,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00, //4
0x00,0x00,0x40,0x01,0x82,0x00,0x00,0x00,0x00,0x00, //5
0x00,0x00,0x00,0x00,0x01,6,7,8,9,10, //6
1,2,3,4,5,6,7,8,9,10, //7
1,2,3,4,5,6,7,8,9,10, //8
1,2,3,4,5,6,7,8,9,10, //9
1,2,3,4,5,6,7,8,9,10, //10
1,2,3,4,5,6,7,8,9,10, //11
1,2,3,4,5,6,7,8,9,10, //12
1,2,3,4,5,6,7,8}; //13


void write_spi( char addr,unsigned wr_byte)
{
int i;
mask=128;
SCSN_DOWN;
delay();
//send byte addres ///
for (i=7;i>=0;i--)
{
SSCK_DOWN;
if ((GET_BIT(addr,mask))!=0) { MOSI_1; } else { MOSI_0; };
mask>>=1;
NOP; NOP;
SSCK_UP;
NOP; NOP;
};
//send byte addres ///
delay();
//write byte from nRF
mask=1;
for (i=7;i>=0;i--)
{
SSCK_DOWN;
if ((GET_BIT(wr_byte,mask))!=0) { MOSI_1; } else { MOSI_0; };
mask<<=1;
NOP;NOP;
SSCK_UP;
NOP; NOP;
};
//write byte from nRF
delay();
SCSN_UP;
};

void main( void )
{



unsigned char i;
WDTCTL = WDTPW + WDTHOLD;
BCSCTL1=RSEL3+XT2OFF;
Init_spi();
while(1)
{
for (i=0;i<55;i++)
{
write_spi(addres[i],byte[i]);
};
while(1);
};
// return 0;
}
Serg_el
Вот назрел вопрос...
Если я хочу записать константу по определенному адресу, то я пишу следующую строку:

const unsigned char x @ 0x01000 = 1;

Но, если я не использую "x" далее в программе, а обращаюсь к адресу 0x01000 другими способами, то компилятор не записывает 1 по этому адресу. Как это обойти?
VAI
ну и обратитесь где нибудь к нему, как к "х".
Serg_el
Цитата(VAI @ Jul 24 2008, 15:08) *
ну и обратитесь где нибудь к нему, как к "х".


А если у меня таких констант десятки и я косвенно к ним обращаюсь через, например, инкремент какой-либо переменной?

Нашел один способ:

if (x)
{
}

компилятор игнорирует этот код, но flash заполняет константами .

Но это как-то не очень красиво. Может есть другие способы?
msalov
Цитата(Serg_el @ Jul 24 2008, 13:01) *
Вот назрел вопрос...
Если я хочу записать константу по определенному адресу, то я пишу следующую строку:

const unsigned char x @ 0x01000 = 1;

Но, если я не использую "x" далее в программе, а обращаюсь к адресу 0x01000 другими способами, то компилятор не записывает 1 по этому адресу. Как это обойти?

Прошу прощения за любопытство, но зачем вам такая константа?
Если необходимо значение хранящееся во флеш по фиксированному адресу, я делаю так
Код
__no_init const unsigned int    PARAM        @  ADDRESS;
Serg_el
Цитата(gotty @ Jul 24 2008, 16:27) *
Прошу прощения за любопытство, но зачем вам такая константа?
Если необходимо значение хранящееся во флеш по фиксированному адресу, я делаю так
Код
__no_init const unsigned int    PARAM        @  ADDRESS;


Я инициализирую устройство константами, затем во время работы они изменяются. Но обращаюсь я к ним не через имя константы.

Нужны известные фиксированные адреса, например, чтобы туда записывать серийный номер при программировании.
msalov
Цитата(Serg_el @ Jul 24 2008, 15:40) *
Я инициализирую устройство константами, затем во время работы они изменяются. Но обращаюсь я к ним не через имя константы.

В таком случае выражение вида
Код
const unsigned char x @ 0x01000 = 1;
в корне неверно, так как вы указываете, что ваша константа никоим образом не изменяется, компилятор конежно же такую константу из памяти выкидывает и заменяет её на значения.
Используйте обьявление которое я вам привёл и наслаждайтесь программированием.
Serg_el
Цитата(gotty @ Jul 24 2008, 16:43) *
В таком случае выражение вида
Код
const unsigned char x @ 0x01000 = 1;
в корне неверно, так как вы указываете, что ваша константа никоим образом не изменяется, компилятор конежно же такую константу из памяти выкидывает и заменяет её на значения.
Используйте обьявление которое я вам привёл и наслаждайтесь программированием.


Ну почему же неверно? Я указываю, что ячейка flash памяти с адресом 0x1000 содержит значение 1. Компилятор понимает, что ее использовать в его нуждах нельзя.
Дальнейшее программирование этого сегмента памяти происходит косвенным способом.

Ваш способ не позволяет инициализировать данную ячейку памяти каким-либо значением. Это только лишь запрет для компилятора на ее использование.
msalov
Цитата(Serg_el @ Jul 24 2008, 15:52) *
Ну почему же неверно? Я указываю, что ячейка flash памяти с адресом 0x1000 содержит значение 1. Компилятор понимает, что ее использовать в его нуждах нельзя.
Дальнейшее программирование этого сегмента памяти происходит косвенным способом.

Ваш способ не позволяет инициализировать данную ячейку памяти каким-либо значением. Это только лишь запрет для компилятора на ее использование.


Вы же сами написали что значение будет время от времени изменяться. А как Вы планируете это делать? Так вот тем же самым способом и инициализируются константы.
P.S. И не забывайте про контроль целостности констант.
Serg_el
Цитата(gotty @ Jul 24 2008, 16:58) *
Вы же сами написали что значение будет время от времени изменяться. А как Вы планируете это делать? Так вот тем же самым способом и инициализируются константы.
P.S. И не забывайте про контроль целостности констант.


Запись flash:
#define SEGMENT_D 0x1000
...

write_flash(SEGMENT_D + offset, data);

offset соответственно определяет смещение относительно начала сегмента,
т.е. для x - offset =0; для y - offset = 1 и т.д.

Т.е. нет смысла при записи использовать какие-либо имена, имея фиксированные адреса.

Производить инициализацию при первом включении по условию задачи нельзя.
msalov
Цитата(Serg_el @ Jul 24 2008, 16:07) *
Запись flash:
#define SEGMENT_D 0x1000
...

write_flash(SEGMENT_D + offset, data);

offset соответственно определяет смещение относительно начала сегмента,
т.е. для x - offset =0; для y - offset = 1 и т.д.

Т.е. нет смысла при записи использовать какие-либо имена, имея фиксированные адреса.

Производить инициализацию при первом включении по условию задачи нельзя.

А в чём проблема записывать константы при программировании кристалла? Или можно сделать обходным путём: брать "значения по-умолчанию" если по адресу записано FF, если, конечно, FF не входит в диапазон допустимых значений.
Serg_el
Цитата(gotty @ Jul 24 2008, 17:12) *
А в чём проблема записывать константы при программировании кристалла? Или можно сделать обходным путём: брать "значения по-умолчанию" если по адресу записано FF, если, конечно, FF не входит в диапазон допустимых значений.


Так я, собственно, всю проблему и описал в своем первом посте smile.gif . По-умолчанию нельзя, т.к. "Производить инициализацию при первом включении по условию задачи нельзя."
rezident
Цитата(Serg_el @ Jul 24 2008, 19:07) *
Производить инициализацию при первом включении по условию задачи нельзя.
Речь о IAR идет? Если да, то выделите в xcl-файле свой собственный сегмент для констант и используйте себе на здоровье в программе его адрес как значение указателя. Без вашей санкции компилятор в выделенном вами сегменте ничего размещать не будет.
Для того, чтобы определить дефолтные значения этих констант еще на этапе программирования кристалла, "пристегните" к прошивке отдельный файл с этими значениями. В последних версиях IAR есть такая опция.
Serg_el
Цитата(rezident @ Jul 24 2008, 17:31) *
Речь о IAR идет? Если да, то выделите в xcl-файле свой собственный сегмент для констант и используйте себе на здоровье в программе его адрес как значение указателя. Без вашей санкции компилятор в выделенном вами сегменте ничего размещать не будет.
Для того, чтобы определить дефолтные значения этих констант еще на этапе программирования кристалла, "пристегните" к прошивке отдельный файл с этими значениями. В последних версиях IAR есть такая опция.


Спасибо. Это уже намного интереснее!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.