Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IAR MSP430 оптимизатор кода
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
KARLSON
Здравтсвуйте.
Ситуация такая:
Есть 3 переменные, которые необходимо разместить во FLASH памяти.

Код
#pragma memory = constseg(INFOD)      // адреса 1000-103F
const volatile signed char nst
            min_ust = 19, // 3 установленное по умолчанию отрицательное значение
            max_ust = 25, // 4 установленное по умолчанию положительное знание
            config = 1;


Кстати, без слова "const" переменные во флеш не размещаются. Кто-нибудь знает почему?

Эти переменные изменяются пользователем путём стирания и записывания флеш памяти. Значения меняются точно.
Далее
есть кусок кода:

Код
if ((DATA.temperatura > max_ust) || (DATA.temperatura < min_ust)) // если температура вышла из диаппазона    
           {
              // делаем то-то
           }
           else // если норма
           {
              // делаем другое
           }


Без оптимизации в настройках компилятора всё нормально, но стоит включить оптимизацию, то в условии в место max_ust и min_ust компилятор ставит 25 и 19 соответственно. Вся загвоздка скорее всего в ключевом слове const. Но без него переменные оказываются в оперативной памяти.
Без оптимизации не могу, т.к. уже код не умещается в памяти контроллера.

Как выйти из сложившейся ситуации?
MrYuran
Цитата(KARLSON @ Oct 27 2010, 13:24) *
Как выйти из сложившейся ситуации?

Свести все данные в структуру и разместить её во флеше.
Мне однажды помогло smile.gif
Вообще, ИАР иногда выкидывает коленца...
V_N
Да имеется такое в IAR я решаю эту проблему путем введения указателей на const и все операции делаю с указателями
rezident
Цитата(KARLSON @ Oct 27 2010, 15:24) *
Как выйти из сложившейся ситуации?
Внимательно изучить документацию на компилятор. У него есть специальные директивы препроцессора по размещению переменных. Квалификатор const к размещению переменных во Flash имеет лишь косвенное отношение.
Если вас устроит способ сделать "втупую", то я практиковал такой финт.

Создаем структуру констант
Код
typedef struct InfoSeg_t
{ float a;
  unsigned int b;
  unsigned int c;
  char d;
  char e;
} InfoSeg_t;

Объявляем константную структуру, инициализируем ее явными значениями и явно задаем адрес размещения
Код
#pragma location=0x1000
const InfoSeg_t InfoSegConst=
{ 1.0f,
  0x1234,
  5678,
  0x0A,
  0x0D
};
#pragma required=InfoSegConst

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

Объявляем еще одну структуру, но неинициализированную, расположенную по тому же адресу, что и первая.
Код
#pragma location=0x1000
__no_init InfoSeg_t InfoSeg;

Далее в программе везде работаем именно со структурой InfoSeg. Поскольку она не инициализирована явными значениями, то компилятор подстановку этих значений не делает, а каждый раз обращается к элементам данной структуры.
При компиляции конечно же выдается Warning, но я на него чихаю потому, что понимаю причину по которой он возникает.
Можно использовать и другие директивы #pragma, которые влияют на размещение переменных. Эта прагма еще из старых версий IAR.
KARLSON
Спосибо всем, особенно rezident. Возможно я поступил по Вашему, но через ассемблер. А именно
Создаётся файл info.s43

Код
public max_ust, min_ust, config, count_clear
ASEG 0x1000
max_ust DB 25
min_ust DB 19
config DB 1
count_clear DB 0
end


А до майна у меня вот что:

Код
extern signed char  max_ust, min_ust, config;
extern unsigned char count_clear;


И никаких указателей и структур не надо. Хотя кому как удобно. И обращаемся к ним прямо по именам. Это при оптимизации медиум, при более сложных не проверю, т.к. уже многое не работает при этом)))
jorikdima
Улыбает конечно смотреть на название переменных, написанных латиницей smile.gif DATA.temperatura smile.gif Ну назовите вы DATA.temperature
А по теме, да, на мой взгляд тоже работать тут надо через константные указатели. Странно что компайлер не принимает во внимание тут volatile, пусть и совместно с const.
К ИАР для МСП у меня тоже есть ряд вопросов. Вечером напишу в эту же тему, если автор не против.
MrYuran
Цитата(KARLSON @ Oct 27 2010, 15:54) *
Спосибо всем, особенно rezident. Возможно я поступил по Вашему, но через ассемблер. А именно
Создаётся файл info.s43

И никаких указателей и структур не надо. Хотя кому как удобно. И обращаемся к ним прямо по именам. Это при оптимизации медиум, при более сложных не проверю, т.к. уже многое не работает при этом)))

А вот это, извините, совершенно через жопу, не побоюсь аллюзий.
Хотя кажется, что проще.

А если что-то не работает при максимальной оптимизации, надо добиваться, чтобы работало.
Иначе может вылезти потом каким-нибудь боком.
Когда "щас я тут чуток поменяю" выливается в неделю борьбы с чудесами на [казалось бы] уже отлаженном проекте.
Mahagam
никаких чудес. простая логика.

"Кстати, без слова "const" переменные во флеш не размещаются. Кто-нибудь знает почему?"
ну потому что без конст - это именно переменные. а как могу переменные располагаться в ПЗУ???

но стоит включить оптимизацию, то в условии в место max_ust и min_ust компилятор ставит 25 и 19 соответственно.
ещё бы. он не дурак, он видит, что при инициализации туда вписали 25 и 19, а потом ни разу нигде по ходу программы прямо не изменяли - он справедливо считает что там 25 и 19. и что нефик их оттуда вычитывать, что можно подставить банальные константы.

весь вопрос как грамотно обмануть компилятор.
rezident
Цитата(Mahagam @ Oct 27 2010, 19:53) *
"Кстати, без слова "const" переменные во флеш не размещаются. Кто-нибудь знает почему?"
ну потому что без конст - это именно переменные. а как могу переменные располагаться в ПЗУ???
Переменные имеющие статический тип объекта - глобальные или static располагаются в ОЗУ, auto (локальные) - на стеке, register - в регистрах. Но переменные имеющие квалификатор типа const совсем не обязательно должны размещаться в ПЗУ. Они могут размещаться там же, где и перечисленные. Хотя переменную const register весьма трудно себе представить smile.gif
jorikdima
Цитата(KARLSON @ Oct 27 2010, 13:24) *
Кстати, без слова "const" переменные во флеш не размещаются. Кто-нибудь знает почему?

Для вашего же блага, чтоб вы не пробовали записать в эти переменные обычным синтаксисом, а работали с флешью как полагается в данном МК.

Цитата(jorikdima @ Oct 27 2010, 16:46) *
К ИАР для МСП у меня тоже есть ряд вопросов. Вечером напишу в эту же тему, если автор не против.

Ну автор, видимо, не против. smile.gif
Итак, есть один cpp модуль и h файл к нему:
main.cpp
Код
#include "io430.h"
#include "b.h"

A a;
B bb;


A::A()
{
    b = &bb;
}


void main()
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;

  a.b->f();
  a.b->f();
  a.b->f();
}

b.h
Код
#include "io430.h"

class B
{
    typedef  unsigned char UINT8;
    typedef  unsigned short UINT16;
    typedef struct
    {
        UINT8 UCCTL1;
        UINT8 UCCTL0;
        UINT16 UCRES[2];
        UINT16 UCBR;
        UINT8 UCMCTL;
        UINT8 UCRES1;
        UINT8 UCSTAT;
        UINT8 UCRES2;
        UINT8 UCRXBUF;
        UINT8 UCRES3;
        UINT8 UCTXBUF;
        UINT8 UCRES4;
        UINT8 UCABCTL;
        UINT8 UCRES5;
        UINT16 UCIRCTL;
        UINT16 UCRES6[4];
        UINT8 UCIE;
        UINT8 UCIFG;
        UINT8 UCIV;
    } REG_STRUCT;
    
    volatile REG_STRUCT* registers;
    
public:
_Pragma("inline=forced")
     void f() {
        volatile REG_STRUCT* const regs = registers;
        while (!(regs->UCIFG & UCTXIFG));    // wait while not ready / for RX
        regs->UCTXBUF = 0xFF;                // write
        while (!(regs->UCIFG & UCRXIFG));    // wait for RX buffer (full)
        volatile UINT8 dummy = regs->UCRXBUF;
    }
    

};



class A
{
public:
    B* b;
    A();

};


extern A a;
extern B bb;

Просьба не обращать внимание на цель кода, код выдернут из рабочего проекта, возможно для демонстрации моего вопроса можно было бы и еще укоротить код. Изначально это был класс-обертка для UART, но не суть.
Есть класс B который имеет важно инлайновый метод f(), есть класс A, который имеет в себе поле-указатель на объект типа B.

В main() я трижды подряд вызываю функцию f(), которую компайлер по моей просьбе инлайнит.
Листинг выглядит так:
Код
        volatile REG_STRUCT* const regs = registers;
005C38    421F 1C00          mov.w   &a,R15                                               ЭТО ПОНЯТНО
005C3C    4F2F               mov.w   @R15,R15
        while (!(regs->UCIFG & UCTXIFG));    // wait while not ready / for RX
005C3E    B3EF 001D          bit.b   #0x2,0x1D(R15)
005C42    2BFD               jnc     0x5C3E
        regs->UCTXBUF = 0xFF;                // write
005C44    43FF 000E          mov.b   #0xFF,0xE(R15)
        while (!(regs->UCIFG & UCRXIFG));    // wait for RX buffer (full)
005C48    B3DF 001D          bit.b   #0x1,0x1D(R15)
005C4C    2BFD               jnc     0x5C48
        volatile UINT8 dummy = regs->UCRXBUF;
005C4E    4FD1 000C 0000     mov.b   0xC(R15),0x0(SP)
        volatile REG_STRUCT* const regs = registers;
005C54    421F 1C00          mov.w   &a,R15                                                НО ЗАЧЕМ ОПЯТЬ?
005C58    4F2F               mov.w   @R15,R15
        while (!(regs->UCIFG & UCTXIFG));    // wait while not ready / for RX
005C5A    B3EF 001D          bit.b   #0x2,0x1D(R15)
005C5E    2BFD               jnc     0x5C5A
        regs->UCTXBUF = 0xFF;                // write
005C60    43FF 000E          mov.b   #0xFF,0xE(R15)
        while (!(regs->UCIFG & UCRXIFG));    // wait for RX buffer (full)
005C64    B3DF 001D          bit.b   #0x1,0x1D(R15)
005C68    2BFD               jnc     0x5C64
        volatile UINT8 dummy = regs->UCRXBUF;
005C6A    4FD1 000C 0000     mov.b   0xC(R15),0x0(SP)
        volatile REG_STRUCT* const regs = registers;
005C70    421F 1C00          mov.w   &a,R15
005C74    4F2F               mov.w   @R15,R15

В начале он определяет адрес начала структуры registers и кладет ее в R15. Затем этим адресом активно пользуется. Но зачем он при каждом вызове f() делает это??? Ведь встраивая функцию компайлер прекрасно видит, что с этим регистром ничего не происходит между вызовами ф-ций.
Второй вопрос. Модифицируем f() так:
Код
_Pragma("inline=forced")
     void f() {
        //volatile REG_STRUCT* const regs = registers;
        while (!(registers->UCIFG & UCTXIFG));    // wait while not ready / for RX
        registers->UCTXBUF = 0xFF;                // write
        while (!(registers->UCIFG & UCRXIFG));    // wait for RX buffer (full)
        volatile UINT8 dummy = registers->UCRXBUF;
    }

Листинг такой () кусок только f():
Код
  a.b->f();
005C38    421F 1C00          mov.w   &a,R15
     void f() {
005C3C    4F2E               mov.w   @R15,R14
        while (!(registers->UCIFG & UCTXIFG));    // wait while not ready / for RX
005C3E    B3EE 001D          bit.b   #0x2,0x1D(R14)
005C42    2BFD               jnc     0x5C3E
        registers->UCTXBUF = 0xFF;                // write
005C44    43FE 000E          mov.b   #0xFF,0xE(R14)
005C48    4F2F               mov.w   @R15,R15                                                          ЗАЧЕМ?
        while (!(registers->UCIFG & UCRXIFG));    // wait for RX buffer (full)
005C4A    B3DF 001D          bit.b   #0x1,0x1D(R15)
005C4E    2BFD               jnc     0x5C4A
        volatile UINT8 dummy = registers->UCRXBUF;
005C50    4FD1 000C 0000     mov.b   0xC(R15),0x0(SP)

Зачем он при проверке флага на прием опять пытается определить начало структуры registers? Ведь в R14 этот адрес уже есть, почему он требует константного указателя? Ведь код линеен и сам указатель registers не объявлен как
Код
    volatile REG_STRUCT* volatile registers;

Что ему с R14 не живется дальше?
Естественно оптимизация полная по скорости.
Спасибо.
LightElf
QUOTE (jorikdima @ Oct 28 2010, 00:43) *
CODE
    volatile REG_STRUCT* volatile registers;

Что ему с R14 не живется дальше?

Имхо надо стандарт (и возможно мануал на иар) читать, как там в иаровских плюсах квалификаторы ассоциируются. Может попробовать так:
CODE
REG_STRUCT volatile * registers;

или
CODE
REG_STRUCT * volatile registers;

Ну и третий вариант (самый корректный)
CODE
REG_STRUCT * registers;
, а volatile прикрутить непосредственно внутри определения структуры к каждому полю.
k155la3
Цитата(KARLSON @ Oct 27 2010, 12:24) *
Здравтсвуйте.
Ситуация такая:
Есть 3 переменные, которые необходимо разместить во FLASH памяти.

[code]#pragma memory = constseg(INFOD) // адреса 1000-103F

. . . . . . . . .
. . . . . . . . .
Без оптимизации в настройках компилятора всё нормально, но стоит включить оптимизацию, то в условии в место max_ust и min_ust компилятор ставит 25 и 19 соответственно. Вся загвоздка скорее всего в ключевом слове const. Но без него переменные оказываются в оперативной памяти.
Без оптимизации не могу, т.к. уже код не умещается в памяти контроллера.

Как выйти из сложившейся ситуации?


Эхо войны .... sm.gif

#pragma location=0x1000
__root const TTestFlashStr InfoSegConst=
{ '1',
'2',
'3',
'4',
'5',
'6'
};
#pragma required=InfoSegConst

Так вроде не должно самоуправничать.
(по крайней мере остается в области флеш на любой оптимизации).
Хотя компилятор умнее нас, и если есть слово "const" может вместо обращения к этой памти заменять на присвоение константы.
LightElf
QUOTE (k155la3 @ Nov 5 2015, 18:07) *
Эхо войны .... sm.gif

#pragma location=0x1000
__root const TTestFlashStr InfoSegConst=
{ '1',
'2',
'3',
'4',
'5',
'6'
};
#pragma required=InfoSegConst

Так вроде не должно самоуправничать.
(по крайней мере остается в области флеш на любой оптимизации).
Хотя компилятор умнее нас, и если есть слово "const" может вместо обращения к этой памти заменять на присвоение константы.

Поставьте __root const volatile TTestFlashStr и будет щастье
den_po
Цитата(k155la3 @ Nov 5 2015, 18:07) *
#pragma location=0x1000
__root const TTestFlashStr InfoSegConst=
{ '1',
'2',
'3',
'4',
'5',
'6'
};
#pragma required=InfoSegConst

Хм. А разве pragma required не перед определением используется?
KRS
Цитата(den_po @ Dec 4 2015, 16:32) *
Хм. А разве pragma required не перед определением используется?

перед! только не перед тем которое где то требуется!
А перед тем которое требует.

т.е. если B для работы нужно А - перед B должна стоять прагма - требуется A
den_po
Не увидел в цитатах ничего про то, кому требуется.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.