Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IAR Optimization
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
mungo
IAR ARM v4.40a.
Недавно очень долго боролся с программкой, которая никак не работала. Определенно глюк компилера.
CODE
volatile int x;

void func1()
{
... код какой-то
// если отработал, х не меняем и выходим
x=0;
}

int main()
{
x=1; func1();
if (x) ...; else ...
x=0; ....
return 0;
}


Суть: потом допер, полез в дизасм. Если в последних строках убрать х=0, то все как-бы работает. Но переменная используется дальше, так что это как-бы и не выход. А в том виде, как оно выглядит, первое присваивание х=1 просто выкидывается. Чтобы он этого не делал, нужно выключать оптимизацию напрочь. Но это ведь не выход, ибо текущий объем прошивки уже за 100 кб вышел.
Поборол косвенно - перестроив порядок команд. То есть искривив программу.

Вопрос: сталкивался ли кто и есть ли смысл обновлять до версии 5? Всё ли там пучком с оптимизатором?
GetSmart
Листинг с глюком в студию.
mungo
Цитата(GetSmart @ Feb 2 2010, 10:36) *
Листинг с глюком в студию.

Я привел суть. Полный лист 100 кб прошивки - это знаете-ли много.

Ах, да. Этот "х" является глобальной переменной, потому что еще прерывание таймера его обрабатывает (типа, если 1, то считывать АЦП).
MALLOY2
Цитата
Я привел суть.


Из вашей сути ничего не ястно
mungo
Цитата(MALLOY2 @ Feb 2 2010, 11:03) *
Из вашей сути ничего не ястно

Значит, не умею объяснять. Ну а на вторую часть вопроса есть ответ? Есть ли известные проблемы оптмизатора в версии 5.11 или 5.41?
GetSmart
Цитата(mungo @ Feb 2 2010, 13:58) *
Я привел суть. Полный лист 100 кб прошивки - это знаете-ли много.

Если не умеете кастрировать программу до самого минимального размера так, чтобы в ней оставался наблюдаться глюк, то "тупизм" скорее всего в вашем коде, а не в оптимизаторе. Поэтому чтобы не быть голословным потратьте на эту кострацию своё время и выложите здесь минимальный листинг с глюком.

А про 5.хх глюки уже были темы на форуме. Либо в этом же подфоруме, либо в "АРМ", либо ещё где-нить.
zltigo
Цитата(mungo @ Feb 2 2010, 12:06) *
Значит, не умею объяснять.

Ну и, судя по тому, что имеете нечто в 100K одним невычленяемым куском, то и с писательством проблемы sad.gif.
О том, что Вы пожелали сделать переменную volatile компилятор должен знать при компиляции всех файлов - почти наверняка в для этой переменой квалификатор volatile в include файлах не указан. Или описанная вами ситуация в корне отличается от реально существующей.
scifi
Цитата(mungo @ Feb 2 2010, 11:29) *
Поборол косвенно - перестроив порядок команд. То есть искривив программу.

Есть серьёзное опасение, что глюк не в компиляторе, а в Вашем коде. Также есть опасение, что глюк не поборен, а просто закопан глубже, откуда его откопать будет труднее.
Dog Pawlowa
Цитата(mungo @ Feb 2 2010, 13:06) *
Есть ли известные проблемы оптмизатора в версии 5.11 или 5.41?

Есть! Мысли не читает! biggrin.gif
Если серьезно, то недавно кто-то тут выкладывал пример не совсем корректной работы со сдвигами при некорректном использовании этих сдвигов.
А все остальное - типичные программистские ошибки, типа одиночный знак равенства в сравнении.
Кстати, хотя бы из-за этой фичи имеет смысл обновить версию, она будет предупреждать.
mungo
Всё-таки не в моей кривости дело. Поставил 5.41.1, собрал, команда осталась на месте. Правда, как обычно, новые особенности. Переделали весь синтаксис асма, и как следствие, все процедуры запуска пришлось брать фирменные из примеров и под себя адаптировать. Да и вообще, если честно, хорошая среда разработки - ИАР. Но вот компилятор - ужас! Какие-то свои стандарты. Раньше пробовал кейл, тот правда не предупреждал о некоторых моих тупизмах (типа вызова из прерывания библиотек), но ему не надо было через одну переменную обозначать volatile. Странно это если честно - переменная и есть она, и кейвордить каждую утомительно.
Сергей Борщ
Цитата(mungo @ Feb 2 2010, 12:52) *
но ему не надо было через одну переменную обозначать volatile.
И ИАРу не надо. Надо только нужные. "через одну" говорит о том, что вы не понимаете смысла ключевого слова volatile.
MALLOY2
Цитата
Ну а на вторую часть вопроса есть ответ?
Вопрос: сталкивался ли кто и есть ли смысл обновлять до версии 5?


Стоит, так как с 5 версии идет другой линкер, и он такой на долго. По этому чем раньше начнете вникать, тем раньше вникните smile.gif

В последних версиях IAR есть глюки в с ядром Cortex-M3, думаю скоро починят, в ARM7 и ARM9 о критических глюках не слышал и не видел.


Цитата
хорошая среда разработки - ИАР. Но вот компилятор - ужас!

Улыбнуло smile.gif, компилятор - один из лучших, а среда разработку - оторвать и выбросить.

Цитата
Ах, да. Этот "х" является глобальной переменной, потому что еще прерывание таймера его обрабатывает (типа, если 1, то считывать АЦП)


Думаю нужно в нужных местах поставить критические секции (запрет\восстановление прерываний), без более подробного кода можно только угадывать....
KSN
IAR ARM 5.30, ядро Cortex M3. При компиляции с оптимизацией уровня medium перестает правильно выполняться функция InitPump. Вот исходник.
CODE

#define Uref ((uint32_t)3300)
#define ADCwidth ((uint32_t)4095)
#define SensitivityXGain ((float)25.2)

#define setbit(a,cool.gif (a |= (1<<b))

#pragma location="FLASH"
__root const float SetPressure[2] = {0.0, 1.0};

struct Pump_struct{
uint8_t channel;
uint16_t sourceid;
uint16_t status;
uint16_t rpm;
uint16_t set_pressure;
uint16_t measure;
float pressure;
float thresoldpressure;
uint16_t lowthresoldrpm;
uint16_t highthresoldrpm;
uint16_t tx_pressure;
uint16_t tx_rpm;
uint16_t lastmessagepressure;
uint16_t lastmessagerpm;
uint32_t timer;
uint32_t timer_message;
uint32_t timer_send;
uint32_t compare_time;
uint16_t pressure_data[PRESSURE_SIZE];
uint8_t pressure_cnt;
uint32_t pressure_sum;
uint32_t rpm_sum;
uint16_t rpm_data[RPM_SIZE];
uint8_t rpm_cnt;
};
struct Pump_struct Pump[2];


void InitPump(uint8_t num)
{
struct Pump_struct *ptrPump;
uint32_t i;
ptrPump = &Pump[num];
ptrPump->status = 0;
ptrPump->sourceid = 0;
ptrPump->rpm = 0;
ptrPump->measure = 0;
ptrPump->pressure = 0;
ptrPump->thresoldpressure = HysteresisPressure[num];
ptrPump->lowthresoldrpm = ThresoldRpm[num][0];
ptrPump->highthresoldrpm = ThresoldRpm[num][1];
ptrPump->tx_pressure = TxPressure[num];
ptrPump->tx_rpm = TxRpm[num];
ptrPump->lastmessagepressure = 0;
ptrPump->lastmessagerpm = 3;
ptrPump->timer = SetTimeOut();
ptrPump->timer_message = SetTimeOut();
ptrPump->timer_send = SetTimeOut();
ptrPump->compare_time = 100;
ptrPump->rpm_cnt = 0;
ptrPump->rpm_sum = 0;
ptrPump->pressure_cnt = 0;
ptrPump->pressure_sum = 0;
for(i=0; i<PRESSURE_SIZE;i++) {
ptrPump->pressure_data[i] = 0;
}
for(i=0; i<RPM_SIZE;i++) {
ptrPump->rpm_data[i] = 0;
}
if(num == 0) {
if(SetPressure[num] != 0)
setbit(ptrPump->status,bit_enable);
ptrPump->set_pressure = (uint16_t)(Offset[num] - (SensitivityXGain*SetPressure[num]*ADCwidth)/Uref);
} else {
ptrPump->set_pressure = (uint16_t)(Offset[num] + (SensitivityXGain*SetPressure[num]*ADCwidth)/Uref);
}
pid_Init(PID_Coeff[num][0],PID_Coeff[num][1],PID_Coeff[num][2],&PID[num]);
ptrPump->channel = num;

}

Привожу также содержание *.icf файла
Код
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__   = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__     = 0x080053FF;   // Max 0x0801FFFF
define symbol __ICFEDIT_region_RAM_start__   = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__     = 0x20004FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__   = 0x500;
define symbol __ICFEDIT_size_heap__     = 0x300;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

define region Flash_region = mem:[from 0x08005400 to 0x080057FF];
define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };
place at start of RAM_region { readwrite section TARGET };
place at end of ROM_region { readonly section .checksum };
place in Flash_region { readonly section FLASH };
place at start of Flash_region { readonly section FLASH2 };

Итак, при уровне оптимизации low, все работает:
CODE

\ In section .text, align 4, keep-with-next
434 void InitPump(uint8_t num)
435 {
\ InitPump:
\ 00000000 70B5 PUSH {R4-R6,LR}
\ 00000002 0400 MOVS R4,R0
436 struct Pump_struct *ptrPump;
437 uint32_t i;
438 ptrPump = &Pump[num];
\ 00000004 E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 00000006 C020 MOVS R0,#+192
\ 00000008 .... LDR.N R1,??DataTable8 ;; Pump
\ 0000000A 04FB0015 MLA R5,R4,R0,R1
439 ptrPump->status = 0;
\ 0000000E 0020 MOVS R0,#+0
\ 00000010 A880 STRH R0,[R5, #+4]
440 ptrPump->sourceid = 0;
\ 00000012 0020 MOVS R0,#+0
\ 00000014 6880 STRH R0,[R5, #+2]
441 ptrPump->rpm = 0;
\ 00000016 0020 MOVS R0,#+0
\ 00000018 E880 STRH R0,[R5, #+6]
450 ptrPump->measure = 0;
\ 0000001A 0020 MOVS R0,#+0
\ 0000001C 6881 STRH R0,[R5, #+10]
451 ptrPump->pressure = 0;
\ 0000001E 0020 MOVS R0,#+0
\ 00000020 E860 STR R0,[R5, #+12]
452 ptrPump->thresoldpressure = HysteresisPressure[num];
\ 00000022 E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 00000024 .... LDR.N R0,??DataTable9 ;; HysteresisPressure
\ 00000026 50F82400 LDR R0,[R0, R4, LSL #+2]
\ 0000002A 2861 STR R0,[R5, #+16]
453 ptrPump->lowthresoldrpm = ThresoldRpm[num][0];
\ 0000002C E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 0000002E 5048 LDR.N R0,??InitPump_0 ;; ThresoldRpm
\ 00000030 50F83400 LDR R0,[R0, R4, LSL #+3]
\ 00000034 A882 STRH R0,[R5, #+20]
454 ptrPump->highthresoldrpm = ThresoldRpm[num][1];
\ 00000036 E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 00000038 4D48 LDR.N R0,??InitPump_0 ;; ThresoldRpm
\ 0000003A 10EBC400 ADDS R0,R0,R4, LSL #+3
\ 0000003E 4068 LDR R0,[R0, #+4]
\ 00000040 E882 STRH R0,[R5, #+22]
455 ptrPump->tx_pressure = TxPressure[num];
\ 00000042 E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 00000044 .... LDR.N R0,??DataTable10 ;; TxPressure
\ 00000046 50F82400 LDR R0,[R0, R4, LSL #+2]
\ 0000004A 2883 STRH R0,[R5, #+24]
456 ptrPump->tx_rpm = TxRpm[num];
\ 0000004C E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 0000004E .... LDR.N R0,??DataTable11 ;; TxRpm
\ 00000050 50F82400 LDR R0,[R0, R4, LSL #+2]
\ 00000054 6883 STRH R0,[R5, #+26]
457 ptrPump->lastmessagepressure = 0;
\ 00000056 0020 MOVS R0,#+0
\ 00000058 A883 STRH R0,[R5, #+28]
458 ptrPump->lastmessagerpm = 3;
\ 0000005A 0320 MOVS R0,#+3
\ 0000005C E883 STRH R0,[R5, #+30]
459 ptrPump->timer = SetTimeOut();
\ 0000005E ........ BL SetTimeOut
\ 00000062 2862 STR R0,[R5, #+32]
460 ptrPump->timer_message = SetTimeOut();
\ 00000064 ........ BL SetTimeOut
\ 00000068 6862 STR R0,[R5, #+36]
461 ptrPump->timer_send = SetTimeOut();
\ 0000006A ........ BL SetTimeOut
\ 0000006E A862 STR R0,[R5, #+40]
462 ptrPump->compare_time = 100;
\ 00000070 6420 MOVS R0,#+100
\ 00000072 E862 STR R0,[R5, #+44]
463 ptrPump->rpm_cnt = 0;
\ 00000074 0020 MOVS R0,#+0
\ 00000076 85F8BC00 STRB R0,[R5, #+188]
464 ptrPump->rpm_sum = 0;
\ 0000007A 0020 MOVS R0,#+0
\ 0000007C A867 STR R0,[R5, #+120]
465 ptrPump->pressure_cnt = 0;
\ 0000007E 0020 MOVS R0,#+0
\ 00000080 85F87000 STRB R0,[R5, #+112]
466 ptrPump->pressure_sum = 0;
\ 00000084 0020 MOVS R0,#+0
\ 00000086 6867 STR R0,[R5, #+116]
467 for(i=0; i<PRESSURE_SIZE;i++) {
\ 00000088 0020 MOVS R0,#+0
\ 0000008A 04E0 B.N ??InitPump_1
468 ptrPump->pressure_data[i] = 0;
\ ??InitPump_2:
\ 0000008C 15EB4001 ADDS R1,R5,R0, LSL #+1
\ 00000090 0022 MOVS R2,#+0
\ 00000092 0A86 STRH R2,[R1, #+48]
469 }
\ 00000094 401C ADDS R0,R0,#+1
\ ??InitPump_1:
\ 00000096 2028 CMP R0,#+32
\ 00000098 F8D3 BCC.N ??InitPump_2
470 for(i=0; i<RPM_SIZE;i++) {
\ 0000009A 0020 MOVS R0,#+0
\ 0000009C 05E0 B.N ??InitPump_3
471 ptrPump->rpm_data[i] = 0;
\ ??InitPump_4:
\ 0000009E 15EB4001 ADDS R1,R5,R0, LSL #+1
\ 000000A2 0022 MOVS R2,#+0
\ 000000A4 A1F87C20 STRH R2,[R1, #+124]
472 }
\ 000000A8 401C ADDS R0,R0,#+1
\ ??InitPump_3:
\ 000000AA 2028 CMP R0,#+32
\ 000000AC F7D3 BCC.N ??InitPump_4
473 if(num == 0) {
\ 000000AE E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 000000B0 002C CMP R4,#+0
\ 000000B2 27D1 BNE.N ??InitPump_5
474 if(SetPressure[num] != 0)
\ 000000B4 E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 000000B6 .... LDR.N R0,??DataTable19 ;; SetPressure
\ 000000B8 50F82400 LDR R0,[R0, R4, LSL #+2]
\ 000000BC 0021 MOVS R1,#+0
\ 000000BE ........ BL __aeabi_cfcmpeq
\ 000000C2 03D0 BEQ.N ??InitPump_6
475 setbit(ptrPump->status,bit_enable);
\ 000000C4 A888 LDRH R0,[R5, #+4]
\ 000000C6 50F00200 ORRS R0,R0,#0x2
\ 000000CA A880 STRH R0,[R5, #+4]
476 ptrPump->set_pressure = (uint16_t)(Offset[num] - (SensitivityXGain*SetPressure[num]*ADCwidth)/Uref);
\ ??InitPump_6:
\ 000000CC E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 000000CE .... LDR.N R0,??DataTable18 ;; Offset
\ 000000D0 50F82400 LDR R0,[R0, R4, LSL #+2]
\ 000000D4 ........ BL __aeabi_ui2f
\ 000000D8 0600 MOVS R6,R0
\ 000000DA E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 000000DC .... LDR.N R0,??DataTable19 ;; SetPressure
\ 000000DE 50F82410 LDR R1,[R0, R4, LSL #+2]
\ 000000E2 .... LDR.N R0,??DataTable20 ;; 0x41c9999a
\ 000000E4 ........ BL __aeabi_fmul
\ 000000E8 .... LDR.N R1,??DataTable21 ;; 0x457ff000
\ 000000EA ........ BL __aeabi_fmul
\ 000000EE .... LDR.N R1,??DataTable22 ;; 0x454e4000
\ 000000F0 ........ BL __aeabi_fdiv
\ 000000F4 0100 MOVS R1,R0
\ 000000F6 3000 MOVS R0,R6
\ 000000F8 ........ BL __aeabi_fsub
\ 000000FC ........ BL __aeabi_f2iz
\ 00000100 2881 STRH R0,[R5, #+8]
\ 00000102 19E0 B.N ??InitPump_7
477 } else {
478 ptrPump->set_pressure = (uint16_t)(Offset[num] + (SensitivityXGain*SetPressure[num]*ADCwidth)/Uref);
\ ??InitPump_5:
\ 00000104 E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 00000106 .... LDR.N R0,??DataTable18 ;; Offset
\ 00000108 50F82400 LDR R0,[R0, R4, LSL #+2]
\ 0000010C ........ BL __aeabi_ui2f
\ 00000110 0600 MOVS R6,R0
\ 00000112 E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 00000114 .... LDR.N R0,??DataTable19 ;; SetPressure
\ 00000116 50F82410 LDR R1,[R0, R4, LSL #+2]
\ 0000011A .... LDR.N R0,??DataTable20 ;; 0x41c9999a
\ 0000011C ........ BL __aeabi_fmul
\ 00000120 .... LDR.N R1,??DataTable21 ;; 0x457ff000
\ 00000122 ........ BL __aeabi_fmul
\ 00000126 .... LDR.N R1,??DataTable22 ;; 0x454e4000
\ 00000128 ........ BL __aeabi_fdiv
\ 0000012C 3100 MOVS R1,R6
\ 0000012E ........ BL __aeabi_fadd
\ 00000132 ........ BL __aeabi_f2iz
\ 00000136 2881 STRH R0,[R5, #+8]
479 }
480 pid_Init(PID_Coeff[num][0],PID_Coeff[num][1],PID_Coeff[num][2],&PID[num]);
\ ??InitPump_7:
\ 00000138 E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 0000013A 1C20 MOVS R0,#+28
\ 0000013C .... LDR.N R1,??DataTable23 ;; PID
\ 0000013E 04FB0013 MLA R3,R4,R0,R1
\ 00000142 E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 00000144 0C20 MOVS R0,#+12
\ 00000146 .... LDR.N R1,??DataTable26 ;; PID_Coeff
\ 00000148 04FB0010 MLA R0,R4,R0,R1
\ 0000014C 8268 LDR R2,[R0, #+8]
\ 0000014E E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 00000150 0C20 MOVS R0,#+12
\ 00000152 .... LDR.N R1,??DataTable26 ;; PID_Coeff
\ 00000154 04FB0010 MLA R0,R4,R0,R1
\ 00000158 4168 LDR R1,[R0, #+4]
\ 0000015A E4B2 UXTB R4,R4 ;; ZeroExt R4,R4,#+24,#+24
\ 0000015C 0C20 MOVS R0,#+12
\ 0000015E .... LDR.N R6,??DataTable26 ;; PID_Coeff
\ 00000160 04FB0060 MLA R0,R4,R0,R6
\ 00000164 0068 LDR R0,[R0, #+0]
\ 00000166 ........ BL pid_Init
481 ptrPump->channel = num;
\ 0000016A 2C70 STRB R4,[R5, #+0]
482
483 }
\ 0000016C 70BD POP {R4-R6,PC} ;; return
\ 0000016E 00BF Nop
\ ??InitPump_0:
\ 00000170 ........ DC32 ThresoldRpm
484



При уровне medium "исчезла" проверка условия
Код
    if(SetPressure[num] != 0)
      setbit(ptrPump->status,bit_enable);

В листинге не вижу, чтобы проверялось это условие.
CODE

\ In section .text, align 2, keep-with-next
435 void InitPump(uint8_t num)
436 {
\ InitPump:
\ 00000000 2DE9F843 PUSH {R3-R9,LR}
\ 00000004 8046 MOV R8,R0
437 struct Pump_struct *ptrPump;
438 uint32_t i;
439 ptrPump = &Pump[num];
\ 00000006 4746 MOV R7,R8
\ 00000008 C020 MOVS R0,#+192
\ 0000000A .... LDR.N R1,??DataTable7 ;; Filter
\ 0000000C 07FB0010 MLA R0,R7,R0,R1
\ 00000010 00F58864 ADD R4,R0,#+1088
440 ptrPump->status = 0;
\ 00000014 0020 MOVS R0,#+0
\ 00000016 A080 STRH R0,[R4, #+4]
441 ptrPump->sourceid = 0;
\ 00000018 6080 STRH R0,[R4, #+2]
442 ptrPump->rpm = 0;
\ 0000001A E080 STRH R0,[R4, #+6]
443 // set_pressure = ((Uoff + Gain*S*P)*4095)/Uref;
444 // set_pressure - значение установленного давления в единицах АЦП;
445 // Uoff - напряжение смещения в мВ.
446 // Gain - коэффициент усиления дифф. усилителя 21.
447 // S - чувствительность датчика, мB/кПа;
448 // P - значение давление в кПа;
449 // Uref - напряжение смещения на АЦП, мВ.
450 // ptrPump->set_pressure = (uint16_t)(((Offset[num]+(float)1.2*fabs(SetPressure[num]))*4095)/3300);
451 ptrPump->measure = 0;
\ 0000001C 6081 STRH R0,[R4, #+10]
452 ptrPump->pressure = 0;
\ 0000001E E060 STR R0,[R4, #+12]
453 ptrPump->thresoldpressure = HysteresisPressure[num];
\ 00000020 .... LDR.N R5,??DataTable8 ;; PID_Coeff
\ 00000022 05EB8706 ADD R6,R5,R7, LSL #+2
\ 00000026 306E LDR R0,[R6, #+96]
\ 00000028 2061 STR R0,[R4, #+16]
454 ptrPump->lowthresoldrpm = ThresoldRpm[num][0];
\ 0000002A 05EBC700 ADD R0,R5,R7, LSL #+3
\ 0000002E 8169 LDR R1,[R0, #+24]
\ 00000030 A182 STRH R1,[R4, #+20]
455 ptrPump->highthresoldrpm = ThresoldRpm[num][1];
\ 00000032 C069 LDR R0,[R0, #+28]
\ 00000034 E082 STRH R0,[R4, #+22]
456 ptrPump->tx_pressure = TxPressure[num];
\ 00000036 306F LDR R0,[R6, #+112]
\ 00000038 2083 STRH R0,[R4, #+24]
457 ptrPump->tx_rpm = TxRpm[num];
\ 0000003A B06E LDR R0,[R6, #+104]
\ 0000003C 6083 STRH R0,[R4, #+26]
458 ptrPump->lastmessagepressure = 0;
\ 0000003E 0020 MOVS R0,#+0
\ 00000040 A083 STRH R0,[R4, #+28]
459 ptrPump->lastmessagerpm = 3;
\ 00000042 0320 MOVS R0,#+3
\ 00000044 E083 STRH R0,[R4, #+30]
460 ptrPump->timer = SetTimeOut();
\ 00000046 ........ BL SetTimeOut
\ 0000004A 2062 STR R0,[R4, #+32]
461 ptrPump->timer_message = SetTimeOut();
\ 0000004C ........ BL SetTimeOut
\ 00000050 6062 STR R0,[R4, #+36]
462 ptrPump->timer_send = SetTimeOut();
\ 00000052 ........ BL SetTimeOut
\ 00000056 A062 STR R0,[R4, #+40]
463 ptrPump->compare_time = 100;
\ 00000058 6420 MOVS R0,#+100
\ 0000005A E062 STR R0,[R4, #+44]
464 ptrPump->rpm_cnt = 0;
\ 0000005C 0020 MOVS R0,#+0
\ 0000005E 84F8BC00 STRB R0,[R4, #+188]
465 ptrPump->rpm_sum = 0;
\ 00000062 04F17000 ADD R0,R4,#+112
\ 00000066 0021 MOVS R1,#+0
\ 00000068 8160 STR R1,[R0, #+8]
466 ptrPump->pressure_cnt = 0;
\ 0000006A 84F87010 STRB R1,[R4, #+112]
467 ptrPump->pressure_sum = 0;
\ 0000006E 4160 STR R1,[R0, #+4]
468 for(i=0; i<PRESSURE_SIZE;i++) {
\ 00000070 0846 MOV R0,R1
\ 00000072 0246 MOV R2,R0
\ 00000074 03E0 B.N ??InitPump_0
469 ptrPump->pressure_data[i] = 0;
\ ??InitPump_1:
\ 00000076 04EB4001 ADD R1,R4,R0, LSL #+1
\ 0000007A 0A86 STRH R2,[R1, #+48]
470 }
\ 0000007C 401C ADDS R0,R0,#+1
\ ??InitPump_0:
\ 0000007E 2028 CMP R0,#+32
\ 00000080 F9D3 BCC.N ??InitPump_1
471 for(i=0; i<RPM_SIZE;i++) {
\ 00000082 1046 MOV R0,R2
\ 00000084 04E0 B.N ??InitPump_2
472 ptrPump->rpm_data[i] = 0;
\ ??InitPump_3:
\ 00000086 04EB4001 ADD R1,R4,R0, LSL #+1
\ 0000008A A1F87C20 STRH R2,[R1, #+124]
473 }
\ 0000008E 401C ADDS R0,R0,#+1
\ ??InitPump_2:
\ 00000090 2028 CMP R0,#+32
\ 00000092 F8D3 BCC.N ??InitPump_3
474 if(num == 0) {
\ 00000094 B8F1000F CMP R8,#+0
\ 00000098 03D1 BNE.N ??InitPump_4
475 if(SetPressure[num] != 0) // ??? Нет проверки!
476 setbit(ptrPump->status,bit_enable);
477 ptrPump->set_pressure = (uint16_t)(Offset[num] - (SensitivityXGain*SetPressure[num]*ADCwidth)/Uref);
\ 0000009A 40F26F30 MOVW R0,#+879
\ 0000009E 2081 STRH R0,[R4, #+8]
\ 000000A0 13E0 B.N ??InitPump_5
478 } else {
479 ptrPump->set_pressure = (uint16_t)(Offset[num] + (SensitivityXGain*SetPressure[num]*ADCwidth)/Uref);
\ ??InitPump_4:
\ 000000A2 B06D LDR R0,[R6, #+88]
\ 000000A4 ........ BL __aeabi_ui2f
\ 000000A8 8146 MOV R9,R0
\ 000000AA 316D LDR R1,[R6, #+80]
\ 000000AC .... LDR.N R0,??DataTable9 ;; 0x41c9999a
\ 000000AE ........ BL __aeabi_fmul
\ 000000B2 .... LDR.N R1,??DataTable10 ;; 0x457ff000
\ 000000B4 ........ BL __aeabi_fmul
\ 000000B8 .... LDR.N R1,??DataTable11 ;; 0x454e4000
\ 000000BA ........ BL __aeabi_fdiv
\ 000000BE 4946 MOV R1,R9
\ 000000C0 ........ BL __aeabi_fadd
\ 000000C4 ........ BL __aeabi_f2iz
\ 000000C8 2081 STRH R0,[R4, #+8]
480 }
481 pid_Init(PID_Coeff[num][0],PID_Coeff[num][1],PID_Coeff[num][2],&PID[num]);
\ ??InitPump_5:
\ 000000CA 0C20 MOVS R0,#+12
\ 000000CC 7843 MULS R0,R7,R0
\ 000000CE 4119 ADDS R1,R0,R5
\ 000000D0 1C22 MOVS R2,#+28
\ 000000D2 .... LDR.N R3,??DataTable12 ;; Can_Tx
\ 000000D4 07FB0232 MLA R2,R7,R2,R3
\ 000000D8 02F17C03 ADD R3,R2,#+124
\ 000000DC 8A68 LDR R2,[R1, #+8]
\ 000000DE 4968 LDR R1,[R1, #+4]
\ 000000E0 4059 LDR R0,[R0, R5]
\ 000000E2 ........ BL pid_Init
482 ptrPump->channel = num;
\ 000000E6 84F80080 STRB R8,[R4, #+0]
483
484 }
\ 000000EA BDE8F183 POP {R0,R4-R9,PC} ;; return
485

Возможно, что я некорректно написал код, но найти не могу, что именно неправильно.
zltigo
Цитата(KSN @ Mar 4 2010, 09:13) *
Возможно, что я некорректно написал код, но найти не могу, что именно неправильно.

Жуткий исходник sad.gif. Ну а выбрасывает совершенно правильно - Вы сравниваете две константы.
IgorKossak
Цитата(KSN @ Mar 4 2010, 08:13) *
При уровне medium "исчезла" проверка условия
Код
    if(SetPressure[num] != 0)
      setbit(ptrPump->status,bit_enable);

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

А теперь если вставить в Вашу коротенькую выдержку то, что необходимо для понимания, то получится следующее (на что коротко указал zltigo):
Код
__root const float SetPressure[2] = {0.0, 1.0};
///
if(num == 0) {
    if(SetPressure[num] != 0)
        setbit(ptrPump->status,bit_enable);

Иначе говоря, если num == 0, то SetPressure[0] == 0, следовательно и проверять условие не нужно и выполнять следующую строку тоже, что компилятор и делает.
KSN
Ага, понял. Просто без const переменная не размещается во flash (одну страницу использую как "eeprom" для настроек). Тогда получается, что надо в RAM создать копию "eeprom" и работать с ним?
zltigo
Цитата(KSN @ Mar 4 2010, 10:58) *
Тогда получается, что надо в RAM создать копию "eeprom" и работать с ним?

Или работать с указателем на область конфигурации, который совершенно не обязательно должен декларироваться, как указатель на константы. Ну и исходник sad.gif sad.gif - имена констант (про имена в венгерском стиле молчу), макрос без скобок, стуктуры без typedef, всякие байтовые переменные, неиспользование memset(), явные преобразования типов без надобности.....
Сергей Борщ
Цитата(KSN @ Mar 4 2010, 09:58) *
Ага, понял. Просто без const переменная не размещается во flash (одну страницу использую как "eeprom" для настроек).
Логика подсказывает, что в этом случае нужно делать const volatile.
KSN
Цитата(Сергей Борщ @ Mar 4 2010, 14:36) *
Логика подсказывает, что в этом случае нужно делать const volatile.

Тоже так думал, на что компилятор возражал: Error[Be006]: Conflicting attributes for segment/section "FLASH"
KSN
В продолжение ответов на мой вопрос возник еще один вопрос о использовании указателя на область конфигурации. Каким способом "настраивать" его на необходимую переменную? Пока я вижу 1 способ:
Код
#define VALUE_ONE 0
#define VALUE_TWO 1

#pragma location="FLASH"
__root const uint32_t  valueOne = 2000;
#pragma location="FLASH"
__root const uint32_t  valueTwo = 3000;

uint32_t* toFlash[] = {
(uint32_t*)&  valueOne,
(uint32_t*)&  valueTwo,
};
.....
temp = *toFlash[VALUE_ONE]; // работаю со значением valueOne


Хотел следующий способ использовать:
Код
#pragma location="FLASH"
__root const uint32_t  valueOne = 2000;
#pragma location="FLASH"
__root const uint32_t  valueTwo = 3000;

uint32_t* toFlash;
.....
toFlash = (uint32_t*)&valueOne;
temp = *toFlash;

но, при оптимизации подставляется значение константы. Еще вариант: для каждой переменной создавать свою section, но будет очень монстроидально. Есть еще варианты?
zltigo
Цитата(KSN @ Mar 5 2010, 14:04) *
я вижу...

Непонятная каша какая-то sad.gif.
Говорите, что где-то во Flash находится СТРУКТУРА со всеми Вашими конфигурационными данными - присваиваете этот адрес ГЛОБАЛЬНОМУ указателю на структуру. И работаете с ней.
MrYuran
Цитата(KSN @ Mar 5 2010, 14:04) *
Есть еще варианты?

Использовать структуры.
Sajan
Цитата(Сергей Борщ @ Mar 4 2010, 12:36) *
Логика подсказывает, что в этом случае нужно делать const volatile.

А для этого желательно понять простые вещи:
Модификатор const распологает константу в флэш-памяти (ROM) без иниицализации, просто число.
Переменная без модификатора располагается в RAM и инициализируется в коде программы.
Модификатор volatile указывает, что переменная может быть изменена "извне" и данный модификатор часто используется для того, чтобы код с использованием такой переменной не оптимизировался, даже с включенной оптимизацией. Соответственно с константой его в принципе нельзя использовать.
aaarrr
Цитата(Sajan @ Apr 27 2010, 14:30) *
Соответственно с константой его в принципе нельзя использовать.

Откуда вдруг такой вывод? Еще как можно.
sigmaN
Для примера возьмем read only регистр какой-нибудь.
Его правильнее объявить как volatile const, чтобы компилятор случае чего ругался, если кто-то захочет(по неосторожности) писАть в этот рид онли регистр.
В тоже время volatile заставит компилятор при обращении к регистру каждый раз РЕАЛЬНО СЧИТЫВАТЬ данные, а не заниматься оптимизацией.
dxp
Цитата(Sajan @ Apr 27 2010, 17:30) *
Модификатор const распологает константу в флэш-памяти (ROM) без иниицализации, просто число.

Заблуждение. Где лежат константыне объекты том же AVR? И в любом загружаемом проце - хоть пень, хоть DSP какой-нить? smile.gif Констатный объект - это такой, который не должен и не может быть изменен во время работы программы (при попытке сделать это обещано неопредленное поведение). А то, что там, где можно безопасно размещать такие объекты в ПЗУ, так это частный случай, и компилятор разумно пользуется этой возможностью.

Цитата(Sajan @ Apr 27 2010, 17:30) *
Модификатор volatile указывает, что переменная может быть изменена "извне" и данный модификатор часто используется для того, чтобы код с использованием такой переменной не оптимизировался, даже с включенной оптимизацией. Соответственно с константой его в принципе нельзя использовать.

Уже привели пример: read only special function register. Например, регистр данных приемника UART'а - чтение из него, как правило, сбрасывает флаг прерывания.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.