KARLSON 1 27 октября, 2010 Опубликовано 27 октября, 2010 · Жалоба Здравтсвуйте. Ситуация такая: Есть 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 27 27 октября, 2010 Опубликовано 27 октября, 2010 · Жалоба Как выйти из сложившейся ситуации? Свести все данные в структуру и разместить её во флеше. Мне однажды помогло :) Вообще, ИАР иногда выкидывает коленца... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vasil_Riabko 1 27 октября, 2010 Опубликовано 27 октября, 2010 · Жалоба Да имеется такое в IAR я решаю эту проблему путем введения указателей на const и все операции делаю с указателями Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 27 октября, 2010 Опубликовано 27 октября, 2010 · Жалоба Как выйти из сложившейся ситуации?Внимательно изучить документацию на компилятор. У него есть специальные директивы препроцессора по размещению переменных. Квалификатор 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 1 27 октября, 2010 Опубликовано 27 октября, 2010 · Жалоба Спосибо всем, особенно 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 0 27 октября, 2010 Опубликовано 27 октября, 2010 · Жалоба Улыбает конечно смотреть на название переменных, написанных латиницей :) DATA.temperatura :) Ну назовите вы DATA.temperature А по теме, да, на мой взгляд тоже работать тут надо через константные указатели. Странно что компайлер не принимает во внимание тут volatile, пусть и совместно с const. К ИАР для МСП у меня тоже есть ряд вопросов. Вечером напишу в эту же тему, если автор не против. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 27 октября, 2010 Опубликовано 27 октября, 2010 · Жалоба Спосибо всем, особенно rezident. Возможно я поступил по Вашему, но через ассемблер. А именно Создаётся файл info.s43 И никаких указателей и структур не надо. Хотя кому как удобно. И обращаемся к ним прямо по именам. Это при оптимизации медиум, при более сложных не проверю, т.к. уже многое не работает при этом))) А вот это, извините, совершенно через жопу, не побоюсь аллюзий. Хотя кажется, что проще. А если что-то не работает при максимальной оптимизации, надо добиваться, чтобы работало. Иначе может вылезти потом каким-нибудь боком. Когда "щас я тут чуток поменяю" выливается в неделю борьбы с чудесами на [казалось бы] уже отлаженном проекте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mahagam 0 27 октября, 2010 Опубликовано 27 октября, 2010 · Жалоба никаких чудес. простая логика. "Кстати, без слова "const" переменные во флеш не размещаются. Кто-нибудь знает почему?" ну потому что без конст - это именно переменные. а как могу переменные располагаться в ПЗУ??? но стоит включить оптимизацию, то в условии в место max_ust и min_ust компилятор ставит 25 и 19 соответственно. ещё бы. он не дурак, он видит, что при инициализации туда вписали 25 и 19, а потом ни разу нигде по ходу программы прямо не изменяли - он справедливо считает что там 25 и 19. и что нефик их оттуда вычитывать, что можно подставить банальные константы. весь вопрос как грамотно обмануть компилятор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 27 октября, 2010 Опубликовано 27 октября, 2010 · Жалоба "Кстати, без слова "const" переменные во флеш не размещаются. Кто-нибудь знает почему?" ну потому что без конст - это именно переменные. а как могу переменные располагаться в ПЗУ??? Переменные имеющие статический тип объекта - глобальные или static располагаются в ОЗУ, auto (локальные) - на стеке, register - в регистрах. Но переменные имеющие квалификатор типа const совсем не обязательно должны размещаться в ПЗУ. Они могут размещаться там же, где и перечисленные. Хотя переменную const register весьма трудно себе представить :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jorikdima 0 27 октября, 2010 Опубликовано 27 октября, 2010 · Жалоба Кстати, без слова "const" переменные во флеш не размещаются. Кто-нибудь знает почему? Для вашего же блага, чтоб вы не пробовали записать в эти переменные обычным синтаксисом, а работали с флешью как полагается в данном МК. К ИАР для МСП у меня тоже есть ряд вопросов. Вечером напишу в эту же тему, если автор не против. Ну автор, видимо, не против. :) Итак, есть один 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 0 29 октября, 2010 Опубликовано 29 октября, 2010 · Жалоба volatile REG_STRUCT* volatile registers; Что ему с R14 не живется дальше? Имхо надо стандарт (и возможно мануал на иар) читать, как там в иаровских плюсах квалификаторы ассоциируются. Может попробовать так: REG_STRUCT volatile * registers; или REG_STRUCT * volatile registers; Ну и третий вариант (самый корректный) REG_STRUCT * registers; , а volatile прикрутить непосредственно внутри определения структуры к каждому полю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 5 ноября, 2015 Опубликовано 5 ноября, 2015 (изменено) · Жалоба Здравтсвуйте. Ситуация такая: Есть 3 переменные, которые необходимо разместить во FLASH памяти. #pragma memory = constseg(INFOD) // адреса 1000-103F . . . . . . . . . . . . . . . . . . Без оптимизации в настройках компилятора всё нормально, но стоит включить оптимизацию, то в условии в место max_ust и min_ust компилятор ставит 25 и 19 соответственно. Вся загвоздка скорее всего в ключевом слове const. Но без него переменные оказываются в оперативной памяти. Без оптимизации не могу, т.к. уже код не умещается в памяти контроллера. Как выйти из сложившейся ситуации? Эхо войны .... :) #pragma location=0x1000 __root const TTestFlashStr InfoSegConst= { '1', '2', '3', '4', '5', '6' }; #pragma required=InfoSegConst Так вроде не должно самоуправничать. (по крайней мере остается в области флеш на любой оптимизации). Хотя компилятор умнее нас, и если есть слово "const" может вместо обращения к этой памти заменять на присвоение константы. Изменено 5 ноября, 2015 пользователем k155la3 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LightElf 0 4 декабря, 2015 Опубликовано 4 декабря, 2015 · Жалоба Эхо войны .... :) #pragma location=0x1000 __root const TTestFlashStr InfoSegConst= { '1', '2', '3', '4', '5', '6' }; #pragma required=InfoSegConst Так вроде не должно самоуправничать. (по крайней мере остается в области флеш на любой оптимизации). Хотя компилятор умнее нас, и если есть слово "const" может вместо обращения к этой памти заменять на присвоение константы. Поставьте __root const volatile TTestFlashStr и будет щастье Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
den_po 0 4 декабря, 2015 Опубликовано 4 декабря, 2015 · Жалоба #pragma location=0x1000 __root const TTestFlashStr InfoSegConst= { '1', '2', '3', '4', '5', '6' }; #pragma required=InfoSegConst Хм. А разве pragma required не перед определением используется? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 6 декабря, 2015 Опубликовано 6 декабря, 2015 · Жалоба Хм. А разве pragma required не перед определением используется? перед! только не перед тем которое где то требуется! А перед тем которое требует. т.е. если B для работы нужно А - перед B должна стоять прагма - требуется A Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться