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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> IAR MSP430 оптимизатор кода
KARLSON
сообщение Oct 27 2010, 09:24
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 5-05-06
Из: Нижегородская обл.
Пользователь №: 16 819



Здравтсвуйте.
Ситуация такая:
Есть 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. Но без него переменные оказываются в оперативной памяти.
Без оптимизации не могу, т.к. уже код не умещается в памяти контроллера.

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


--------------------
Кризис - это не отсутствие денег, а отсутствие идей! Учитесь и никаких кризисов не будет.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Oct 27 2010, 09:49
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



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

Свести все данные в структуру и разместить её во флеше.
Мне однажды помогло smile.gif
Вообще, ИАР иногда выкидывает коленца...


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
V_N
сообщение Oct 27 2010, 09:59
Сообщение #3


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

Группа: Свой
Сообщений: 162
Регистрация: 12-01-09
Из: Харьков
Пользователь №: 43 270



Да имеется такое в IAR я решаю эту проблему путем введения указателей на const и все операции делаю с указателями
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 27 2010, 11:32
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(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.
Go to the top of the page
 
+Quote Post
KARLSON
сообщение Oct 27 2010, 11:54
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 5-05-06
Из: Нижегородская обл.
Пользователь №: 16 819



Спосибо всем, особенно 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;


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


--------------------
Кризис - это не отсутствие денег, а отсутствие идей! Учитесь и никаких кризисов не будет.
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Oct 27 2010, 12:46
Сообщение #6


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



Улыбает конечно смотреть на название переменных, написанных латиницей smile.gif DATA.temperatura smile.gif Ну назовите вы DATA.temperature
А по теме, да, на мой взгляд тоже работать тут надо через константные указатели. Странно что компайлер не принимает во внимание тут volatile, пусть и совместно с const.
К ИАР для МСП у меня тоже есть ряд вопросов. Вечером напишу в эту же тему, если автор не против.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Oct 27 2010, 12:58
Сообщение #7


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(KARLSON @ Oct 27 2010, 15:54) *
Спосибо всем, особенно rezident. Возможно я поступил по Вашему, но через ассемблер. А именно
Создаётся файл info.s43

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

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

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


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Mahagam
сообщение Oct 27 2010, 13:53
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 322
Регистрация: 2-07-04
Из: Minsk
Пользователь №: 240



никаких чудес. простая логика.

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

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

весь вопрос как грамотно обмануть компилятор.
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 27 2010, 17:16
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Mahagam @ Oct 27 2010, 19:53) *
"Кстати, без слова "const" переменные во флеш не размещаются. Кто-нибудь знает почему?"
ну потому что без конст - это именно переменные. а как могу переменные располагаться в ПЗУ???
Переменные имеющие статический тип объекта - глобальные или static располагаются в ОЗУ, auto (локальные) - на стеке, register - в регистрах. Но переменные имеющие квалификатор типа const совсем не обязательно должны размещаться в ПЗУ. Они могут размещаться там же, где и перечисленные. Хотя переменную const register весьма трудно себе представить smile.gif
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Oct 27 2010, 20:43
Сообщение #10


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



Цитата(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 не живется дальше?
Естественно оптимизация полная по скорости.
Спасибо.
Go to the top of the page
 
+Quote Post
LightElf
сообщение Oct 29 2010, 18:41
Сообщение #11


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

Группа: Участник
Сообщений: 180
Регистрация: 5-04-09
Пользователь №: 47 205



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 прикрутить непосредственно внутри определения структуры к каждому полю.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Nov 5 2015, 15:07
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(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" может вместо обращения к этой памти заменять на присвоение константы.


Сообщение отредактировал k155la3 - Nov 5 2015, 15:20
Go to the top of the page
 
+Quote Post
LightElf
сообщение Dec 4 2015, 12:59
Сообщение #13


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

Группа: Участник
Сообщений: 180
Регистрация: 5-04-09
Пользователь №: 47 205



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 и будет щастье
Go to the top of the page
 
+Quote Post
den_po
сообщение Dec 4 2015, 13:32
Сообщение #14


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

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(k155la3 @ Nov 5 2015, 18:07) *
#pragma location=0x1000
__root const TTestFlashStr InfoSegConst=
{ '1',
'2',
'3',
'4',
'5',
'6'
};
#pragma required=InfoSegConst

Хм. А разве pragma required не перед определением используется?
Go to the top of the page
 
+Quote Post
KRS
сообщение Dec 6 2015, 19:35
Сообщение #15


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



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

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

т.е. если B для работы нужно А - перед B должна стоять прагма - требуется A
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 28th June 2025 - 22:01
Рейтинг@Mail.ru


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