Zeal0t 0 5 января, 2019 Опубликовано 5 января, 2019 (изменено) · Жалоба Добрый день. Имеем STM32L1 семейства. Столкнулся со странностью оптимизатора IAR, или что то недопонимаю сам. Имеем следующие структуры typedef __packed struct { uint32_t ID; uint16_t VERS; uint32_t UID; uint32_t DeviceType; uint32_t DeviceNumber; uint32_t CreateTime; uint32_t ExpireTime; } tagExpireKey; typedef __packed struct { uint8_t G[10]; } tagExpireKeyCrypt; typedef __packed struct { tagExpireKey Data; tagExpireKeyCrypt Crypt; uint32_t ControlCRC; } tagExpireKeyDevice; глобальную переменную этого типа tagExpireKeyDevice License; Переменная License загружается выше по тексту программы. Данные в полях всех структур корректные. Далее в тексте программы выполняются 2 проверки: uint32_t CurTime; CurTime = FRTC.GetSeconds(); for (;;) { ... if (CurTime < LicenseCUR.Data.CreateTime) break; if (CurTime > LicenseCUR.Data.ExpireTime) break; ... } что в asm выглядит следующим образом \ ??DataTable1_2: \ 00000000 0x........ DC32 LicenseCUR \ ??DataTable1_4: \ 00000000 0x........ DC32 FRTC ... \ 00000004 0x.... LDR.N R5,??DataTable1_2 ... 83 CurTime = FRTC.GetSeconds(); \ 00000020 0x.... LDR.N R6,??DataTable1_4 \ 00000028 0x4630 MOV R0,R6 \ 0000002A 0x.... 0x.... BL _ZN4TRTC10GetSecondsEv ... 95 if (CurTime < LicenseCUR.Data.CreateTime) break; \ 0000002E 0xF8D5 0x1012 LDR R1,[R5, #+18] \ 00000032 0x4288 CMP R0,R1 \ 00000034 0xBF24 ITT CS \ 00000036 0xF8D5 0x1016 LDRCS R1,[R5, #+22] \ 0000003A 0x4281 CMPCS R1,R0 99 if (CurTime > LicenseCUR.Data.ExpireTime) break; \ 0000003C 0xD303 BCC.N ??CheckCurLicense_0 проходя в отладчике этот кусок кода, увидел что при первом сравнении в R1 при выполнении LDR R1,[R5, #+18] была выполнена загрузка значения поля LicenseCUR.Data.CreateTime и условие программы было выполнено, а вот при выполнении LDRCS R1,[R5, #+22] значение поля LicenseCUR.Data.ExpireTime в R1 не загружается. если изменить текст программы как asm("nop"); if (CurTime < LicenseCUR.Data.CreateTime) break; asm("nop"); if (CurTime > LicenseCUR.Data.ExpireTime) break; получаем следующий корректно работающий листинг: 94 asm("nop"); \ 0000002E 0xBF00 nop 95 if (CurTime < LicenseCUR.Data.CreateTime) break; \ 00000030 0xF8D5 0x1012 LDR R1,[R5, #+18] \ 00000034 0x4288 CMP R0,R1 \ 00000036 0xD308 BCC.N ??CheckCurLicense_0 96 97 asm("nop"); \ 00000038 0xBF00 nop 98 // время лицензии закончилось 99 if (CurTime > LicenseCUR.Data.ExpireTime) break; \ 0000003A 0xF8D5 0x1016 LDR R1,[R5, #+22] \ 0000003E 0x4281 CMP R1,R0 \ 00000040 0xD303 BCC.N ??CheckCurLicense_0 т.е. вставлен nop, который сбрасывает очередь, если не путаю ничего и компилятор сделал обе загрузки через LDR R1,[R5, #+18] LDR R1,[R5, #+22] в чем моя, или не моя, ошибка? то что инструкция <ITT CS> и далее <LDRCS> не верно работают с упакованными структурами или что то другое? спасибо. p.s. Если модераторы посчитают необходимым - можно перенести тему в ARM форум. Не стал дублировать сообщения. Изменено 5 января, 2019 пользователем Zeal0t Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 5 января, 2019 Опубликовано 5 января, 2019 · Жалоба 51 минуту назад, Zeal0t сказал: \ ??DataTable1_2: \ 00000000 0x........ DC32 LicenseCUR \ ??DataTable1_4: \ 00000000 0x........ DC32 FRTC ... \ 00000004 0x.... LDR.N R5,??DataTable1_2 ... 83 CurTime = FRTC.GetSeconds(); \ 00000020 0x.... LDR.N R6,??DataTable1_4 \ 00000028 0x4630 MOV R0,R6 \ 0000002A 0x.... 0x.... BL _ZN4TRTC10GetSecondsEv ... 95 if (CurTime < LicenseCUR.Data.CreateTime) break; \ 0000002E 0xF8D5 0x1012 LDR R1,[R5, #+18] \ 00000032 0x4288 CMP R0,R1 \ 00000034 0xBF24 ITT CS \ 00000036 0xF8D5 0x1016 LDRCS R1,[R5, #+22] \ 0000003A 0x4281 CMPCS R1,R0 99 if (CurTime > LicenseCUR.Data.ExpireTime) break; \ 0000003C 0xD303 BCC.N ??CheckCurLicense_0 проходя в отладчике этот кусок кода, увидел что при первом сравнении в R1 при выполнении LDR R1,[R5, #+18] была выполнена загрузка значения поля LicenseCUR.Data.CreateTime и условие программы было выполнено, а вот при выполнении LDRCS R1,[R5, #+22] значение поля LicenseCUR.Data.ExpireTime в R1 не загружается. Что значит "условие программы было выполнено"? Флаг C после команды "CMP R0,R1" чему равен? Раз "значение поля LicenseCUR.Data.ExpireTime в R1 не загружается", то очевидно что флаг C в этот момент был ==0. Тогда что Вас удивляет? Цитата в чем моя, или не моя, ошибка? Видимо в том, что Вы не знаете как работают префиксы условного выполнения команд в ARM. Прочитайте мануал по системе команд Cortex-M. 52 минуты назад, Zeal0t сказал: т.е. вставлен nop, который сбрасывает очередь, если не путаю ничего и компилятор сделал обе загрузки через NOP не сбрасывает никаких "очередей". После вставки лишних команд оптимизатор решил, что использовать условные переходы выгоднее, чем префиксы условного выполнения команд. Только и всего. Совет: Если отлаживаете по шагам, то отключайте оптимизацию. Или изучайте ассемблер и отлаживайте по ассемблерному коду. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zeal0t 0 5 января, 2019 Опубликовано 5 января, 2019 · Жалоба 2 hours ago, jcxz said: Что значит "условие программы было выполнено"? Флаг C после команды "CMP R0,R1" чему равен? Раз "значение поля LicenseCUR.Data.ExpireTime в R1 не загружается", то очевидно что флаг C в этот момент был ==0. Тогда что Вас удивляет? Видимо в том, что Вы не знаете как работают префиксы условного выполнения команд в ARM. Прочитайте мануал по системе команд Cortex-M. NOP не сбрасывает никаких "очередей". После вставки лишних команд оптимизатор решил, что использовать условные переходы выгоднее, чем префиксы условного выполнения команд. Только и всего. Совет: Если отлаживаете по шагам, то отключайте оптимизацию. Или изучайте ассемблер и отлаживайте по ассемблерному коду. Да было бы там что отлаживать - 2 банальных условия. В asm листинги полез уж после того, как программа не стала работать так как задумывалось. Проблема не в IAR, оптимизации и asm инструкциях. На модуле часов села батарея. Во время очередного прогона часы получили время 0. А я не обратил на это внимания, т.к. был уверен в том, что там все нормально. Уже в процессе разбирательств устройство успело синхронизировать время с актуальным на данный момент и корректно отработал вариант с nop вставками. Поэтому все так и получилось. Спасибо. Проблема решена. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 5 января, 2019 Опубликовано 5 января, 2019 · Жалоба 10 минут назад, Zeal0t сказал: На модуле часов села батарея. Во время очередного прогона часы получили время 0. А я не обратил на это внимания, т.к. был уверен в том, что там все нормально. Там не нормально, потому что в RTC модулях обычно бывают флаги "данные в часах валидны". Когда батарейка садится этот флаг сбрасывается. Естественно при каждом чтении часов нужно смотреть и этот флаг. Раз вы его не смотрите, значит и там тоже не нормально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zeal0t 0 5 января, 2019 Опубликовано 5 января, 2019 (изменено) · Жалоба 6 minutes ago, jcxz said: Там не нормально, потому что в RTC модулях обычно бывают флаги "данные в часах валидны". Когда батарейка садится этот флаг сбрасывается. Естественно при каждом чтении часов нужно смотреть и этот флаг. Раз вы его не смотрите, значит и там тоже не нормально. в DS1388 тоже есть такой флаг? подскажите, если не трудно ) не нужно придираться к людям, даже если сам гуру - все мы с чего то начинали ) Изменено 5 января, 2019 пользователем Zeal0t Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 5 января, 2019 Опубликовано 5 января, 2019 · Жалоба 3 минуты назад, Zeal0t сказал: в DS1388 тоже есть такой флаг? подскажите, если не трудно ) Даже если отдельного бита нет, то следует считанное значение сначала проверять на допустимость (на диапазон). Это и есть - проверка валидности. И только потом его как то использовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 7 января, 2019 Опубликовано 7 января, 2019 · Жалоба On 1/5/2019 at 6:12 PM, Zeal0t said: в DS1388 тоже есть такой флаг? подскажите, если не трудно ) . . . Bit 7: Oscillator Stop Flag (OSF) такие флаги есть в каждом уважающем себя RTC. Он устанавливается при первоначальном включении, а также при зафиксированных внутри RTC сбоях (например провал по питанию при заниженном напряжение резервной батареи). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 7 января, 2019 Опубликовано 7 января, 2019 · Жалоба 2 минуты назад, k155la3 сказал: Bit 7: Oscillator Stop Flag (OSF) Вам, коллега, надо мзду брать за чтение даташитов за лентяев. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 7 января, 2019 Опубликовано 7 января, 2019 · Жалоба 3 minutes ago, jcxz said: Вам, коллега, надо мзду брать за чтение даташитов за лентяев. Не, не чтение. Ctrl<F> Операция, которую я "вырабатывал" годАми тренировок :) На "чтение" ТС у меня может запросить прайс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zeal0t 0 8 января, 2019 Опубликовано 8 января, 2019 · Жалоба 20 hours ago, k155la3 said: Не, не чтение. Ctrl<F> Операция, которую я "вырабатывал" годАми тренировок :) На "чтение" ТС у меня может запросить прайс. Спасибо за предложение. Если будет необходимо - обязательно обращусь. А теперь вопрос не по теме топика. Для jcxz и K155ЛА3. Вы когда делаете какой то новый модуль, или наращиваете функциональность существующего - вот прям вот сразу так все обвешиваете тестами, проверками и прочими защитами? Или все же изначально делается какой более-менее работающий макет и потом, если он взлетел и устраивает, то уже доделываете для него все что по хорошему нужно и необходимо? Или может уважаемые пишут все сразу что может понадобится и, естественно конечно, без ошибок и ляпов? Ну извините раз так. Я почему то считал, что различные форумы и группы именно для этого и созданы - общение и обсуждение. Или может это сейчас стиль общения такой - ткнуть мордой и сказать RTFM? Ну будем тогда знать. Извините что отнял ваше драгоценное время. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 8 января, 2019 Опубликовано 8 января, 2019 · Жалоба 1 час назад, Zeal0t сказал: Вы когда делаете какой то новый модуль, или наращиваете функциональность существующего - вот прям вот сразу так все обвешиваете тестами, проверками и прочими защитами? Если я делаю чтение какого-то устройства, которое может быть в невалидном состоянии, то в функции, возвращающей результат чтения, я обычно предусматриваю возврат спец. значения для этого состояния. Да - делаю это сразу. И вроде это само собой разумеется. 1 час назад, Zeal0t сказал: Или может это сейчас стиль общения такой - ткнуть мордой и сказать RTFM? Ну будем тогда знать. Извините что отнял ваше драгоценное время. PS: Какая-то странная реакция на простое замечание.... Извините что потревожили вашу корону. В мыслях такого не было. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zeal0t 0 8 января, 2019 Опубликовано 8 января, 2019 · Жалоба Просьба к модераторам удалить тему Спасибо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться