|
|
  |
Неверная компиляция при высокой оптимизации под ARM |
|
|
|
May 27 2014, 07:30
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 5-12-06
Пользователь №: 23 160

|
Здравствуйте Есть такая проблема с компиляцией проекта под cortex-m3 (stm32l). Если компилировать с уровнем оптимизации medium все компилируется верно. Но если выставить оптимизацию на high balanced или speed даже если выключить все доступные оптимизации которые доступны при уровне high проект компилируется неверно. Пробовал на IAR ARM 7.1.3 и 7.2.1 Пример функции которая идет в комплекте драйверов ST Код void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) { .... /* Select STOP mode entry --------------------------------------------------*/ if(PWR_STOPEntry == PWR_SLEEPEntry_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __WFE(); } } PWR_SLEEPEntry_WFI = 1; PWR_STOPEntry передается 1; И условие IF ELSE которые по логике должны быть взаимоисключающими выполняются последовательно, т.е. сначала __WFI(); и потом сразу __WFE(); Это видно в отладчике и дизассемблере эти функции идут подряд.
Сообщение отредактировал IgorKossak - May 27 2014, 15:02
Причина редактирования: пользуйтесь тэгами
|
|
|
|
|
May 29 2014, 02:21
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 5-12-06
Пользователь №: 23 160

|
CODE void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_PWR_REGULATOR(PWR_Regulator)); assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); /* Select the regulator state in STOP mode ---------------------------------*/ tmpreg = PWR->CR; /* Clear PDDS and LPDSR bits */ tmpreg &= CR_DS_MASK; /* Set LPDSR bit according to PWR_Regulator value */ tmpreg |= PWR_Regulator; /* Store the new value */ PWR->CR = tmpreg; /* Set SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR |= SCB_SCR_SLEEPDEEP; /* Select STOP mode entry --------------------------------------------------*/ if(PWR_STOPEntry == PWR_SLEEPEntry_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); }
CODE 08002382: 0x4770 BX LR 685 tmpreg = PWR->CR; PWR_EnterSTOPMode: 08002384: PWR_EnterSTOPMode: 0x4a0a LDR.N R2, ??DataTable12_1 ; 0x40007000 (1073770496) 08002386: 0x6813 LDR R3, [R2] 693 PWR->CR = tmpreg; 08002388: 0x089b LSRS R3, R3, #2 0800238a: 0xea40 0x0083 ORR.W R0, R0, R3, LSL #2 0800238e: 0x6010 STR R0, [R2] 08002390: 0x2901 CMP R1, #1 696 SCB->SCR |= SCB_SCR_SLEEPDEEP; 08002392: 0x4808 LDR.N R0, ??DataTable12_6 ; SCR 08002394: 0x6802 LDR R2, [R0] 08002396: 0xf042 0x0204 ORR.W R2, R2, #4 0800239a: 0x6002 STR R2, [R0] 699 if(PWR_STOPEntry == PWR_SLEEPEntry_WFI) 0800239c: 0xbf0c ITE EQ 702 __WFI(); 0800239e: 0xbf30 WFIEQ 707 __WFE(); 080023a0: 0xbf20 WFENE 710 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); 080023a2: 0x6801 LDR R1, [R0] 080023a4: 0xf021 0x0104 BIC.W R1, R1, #4 080023a8: 0x6001 STR R1, [R0] 711 }
Сообщение отредактировал IgorKossak - May 29 2014, 15:16
Причина редактирования: используйте тэги
|
|
|
|
|
May 29 2014, 08:34
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 5-12-06
Пользователь №: 23 160

|
Чет в первый раз слышу чтобы отладчик прошелся по той функции которая не выполняется. Знаю и видел что по коду он может прыгнуть в неожиданные места из-за высокой оптимизации. Да и к тому же при средней оптимизации если я останавливаю программу, то я вижу что отладчик встал на инструкции WFI, при высокой оптимизации он уже встает именно на WFE. Да и нигде в коде я не передаю функции использование WFE, по хорошему компилятор должен был вообще выкинуть ее из функции как неиспользуемую. Вот код при средней оптимизации: CODE 080011fe: 0x4770 BX LR 685 tmpreg = PWR->CR; PWR_EnterSTOPMode: 08001200: PWR_EnterSTOPMode: 0x4a0b LDR.N R2, ??DataTable12_1 ; 0x40007000 (1073770496) 08001202: 0x6813 LDR R3, [R2] 693 PWR->CR = tmpreg; 08001204: 0x089b LSRS R3, R3, #2 08001206: 0xea50 0x0083 ORRS.W R0, R0, R3, LSL #2 0800120a: 0x6010 STR R0, [R2] 696 SCB->SCR |= SCB_SCR_SLEEPDEEP; 0800120c: 0x4809 LDR.N R0, ??DataTable12_6 ; SCR 0800120e: 0x6802 LDR R2, [R0] 08001210: 0xf042 0x0204 ORR.W R2, R2, #4 08001214: 0x6002 STR R2, [R0] 699 if(PWR_STOPEntry == PWR_SLEEPEntry_WFI) 08001216: 0x2901 CMP R1, #1 08001218: 0xd101 BNE.N ??PWR_EnterSTOPMode_0 ; 0x800121e 702 __WFI(); 0800121a: 0xbf30 WFI 0800121c: 0xe000 B.N ??PWR_EnterSTOPMode_1 ; 0x8001220 707 __WFE(); 0800121e: ??PWR_EnterSTOPMode_0: 0xbf20 WFE 710 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); 08001220: ??PWR_EnterSTOPMode_1: 0x6801 LDR R1, [R0] 08001222: 0xf021 0x0104 BIC.W R1, R1, #4 08001226: 0x6001 STR R1, [R0] 711 }
Сообщение отредактировал IgorKossak - May 29 2014, 15:16
Причина редактирования: используйте тэги
|
|
|
|
|
May 29 2014, 09:19
|
Частый гость
 
Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315

|
Цитата(veteq @ May 29 2014, 16:44)  Чет в первый раз слышу чтобы отладчик прошелся по той функции которая не выполняется. Знаю и видел что по коду он может прыгнуть в неожиданные места из-за высокой оптимизации. Да и к тому же при средней оптимизации если я останавливаю программу, то я вижу что отладчик встал на инструкции WFI, при высокой оптимизации он уже встает именно на WFE. Да и нигде в коде я не передаю функции использование WFE, по хорошему компилятор должен был вообще выкинуть ее из функции как неиспользуемую. считайте эти команды составными WFIEQ == IF(EQUAL)WFI WFENE == IF(NOT EQUAL)WFE
Сообщение отредактировал den_po - May 29 2014, 09:19
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|