veteq 0 27 мая, 2014 Опубликовано 27 мая, 2014 (изменено) · Жалоба Здравствуйте Есть такая проблема с компиляцией проекта под 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(); Это видно в отладчике и дизассемблере эти функции идут подряд. Изменено 27 мая, 2014 пользователем IgorKossak пользуйтесь тэгами Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 27 мая, 2014 Опубликовано 27 мая, 2014 · Жалоба Это видно в отладчике и дизассемблере эти функции идут подряд.Покажите дизассемблер. Всей функции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
veteq 0 29 мая, 2014 Опубликовано 29 мая, 2014 (изменено) · Жалоба 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); } 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 } Изменено 29 мая, 2014 пользователем IgorKossak используйте тэги Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
den_po 0 29 мая, 2014 Опубликовано 29 мая, 2014 · Жалоба 0800239e: 0xbf30 WFIEQ 080023a0: 0xbf20 WFENE вот эти EQ и NE в конце означают условие выполнения. выполнится лишь одна из них, в зависимости от флага Z (или как он там в армах называется) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 29 мая, 2014 Опубликовано 29 мая, 2014 · Жалоба вот эти EQ и NE в конце означают условие выполнения.Именно. То, что отладчик показал проход по этой команде еще не означает, что она выполнилась. Подробнее можно узнать в описании команды ITE (на описании этой команды можно голову сломать ). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
veteq 0 29 мая, 2014 Опубликовано 29 мая, 2014 (изменено) · Жалоба Чет в первый раз слышу чтобы отладчик прошелся по той функции которая не выполняется. Знаю и видел что по коду он может прыгнуть в неожиданные места из-за высокой оптимизации. Да и к тому же при средней оптимизации если я останавливаю программу, то я вижу что отладчик встал на инструкции WFI, при высокой оптимизации он уже встает именно на WFE. Да и нигде в коде я не передаю функции использование WFE, по хорошему компилятор должен был вообще выкинуть ее из функции как неиспользуемую. Вот код при средней оптимизации: 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 } Изменено 29 мая, 2014 пользователем IgorKossak используйте тэги Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 29 мая, 2014 Опубликовано 29 мая, 2014 · Жалоба Чет в первый раз слышу чтобы отладчик прошелся по той функции которая не выполняется. Все верно. Только особенность блока IT в том, что некоторые команды (которые имеют ложное условие) при исполнении аппаратно заменяются на NOP. Это гораздо лучше для конвеера, нежели переходы, и для крошечных веток сравнения (как у Вас) очень эффективно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
den_po 0 29 мая, 2014 Опубликовано 29 мая, 2014 (изменено) · Жалоба Чет в первый раз слышу чтобы отладчик прошелся по той функции которая не выполняется. Знаю и видел что по коду он может прыгнуть в неожиданные места из-за высокой оптимизации. Да и к тому же при средней оптимизации если я останавливаю программу, то я вижу что отладчик встал на инструкции WFI, при высокой оптимизации он уже встает именно на WFE. Да и нигде в коде я не передаю функции использование WFE, по хорошему компилятор должен был вообще выкинуть ее из функции как неиспользуемую. считайте эти команды составными WFIEQ == IF(EQUAL)WFI WFENE == IF(NOT EQUAL)WFE Изменено 29 мая, 2014 пользователем den_po Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 29 мая, 2014 Опубликовано 29 мая, 2014 · Жалоба Осталось ещё добавить, что в наборе инструкций ARM (в том, который полный, а не Thumb и проч.) каждая инструкция может быть условной. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться