Integro 0 16 ноября, 2018 Опубликовано 16 ноября, 2018 · Жалоба 1 hour ago, jcxz said: Точку фаулта (PC) знаете? PC ведь указывает на текущее положение, на ту строку дизассемблера которая сейчас выполняется. Нужно смотреть на LR или проще посмотреть callstack если он не затерт Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 16 ноября, 2018 Опубликовано 16 ноября, 2018 · Жалоба 5 минут назад, Integro сказал: PC ведь указывает на текущее положение, на ту строку дизассемблера которая сейчас выполняется. Нужно смотреть на LR или проще посмотреть callstack если он не затерт Под "точкой фаулта (PC)" я имел в виду адрес PC, на котором произошёл fault. haker_fox писал, что у него уже анализируются регистры. По-моему под анализом надо понимать выдачу пользователю содержимого всех регистров CPU + кадра активного стека + расшифровки регистров HF. Типа как в синем окне смерти винды. По-крайней мере у меня во всех проектах сделано именно так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 16 ноября, 2018 Опубликовано 16 ноября, 2018 · Жалоба 5 minutes ago, Integro said: Нужно смотреть на LR или проще посмотреть callstack если он не затерт В fault'е LR не указывает на точку сбоя, её следует взять из стек-фрейма, который точно не затерт, т.к. записан на входе в исключение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Integro 0 16 ноября, 2018 Опубликовано 16 ноября, 2018 · Жалоба 37 minutes ago, jcxz said: Под "точкой фаулта (PC)" я имел в виду адрес PC, на котором произошёл fault. нуда, понял 33 minutes ago, aaarrr said: В fault'е LR не указывает на точку сбоя, её следует взять из стек-фрейма, который точно не затерт, т.к. записан на входе в исключение. Всмысле точно? Перед входом в исключение я могу совершенно "штатно"(случайно) затереть стек и при этом исключение может сработать только при выходе функции (или еще дальше) а не в момент затирания стека. void test(void) { uint8_t dest[1000]; uint32_t src[1000] = {0}; memcpy(dest, src, sizeof(src)); printf("complete"); } В этом случае в стек фрейме будут нули но в LR будет лежать PC+1, адрес в момент HF. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 16 ноября, 2018 Опубликовано 16 ноября, 2018 · Жалоба 15 minutes ago, Integro said: В этом случае в стек фрейме будут нули но в LR будет лежать PC+1, адрес в момент HF. 1. Не будет нулей, будет состояние регистров на момент fault'а. 2. В LR не будет лежать PC+1, механизм исключений Cortex'а вообще такого варианта не предусматривает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 17 ноября, 2018 Опубликовано 17 ноября, 2018 · Жалоба 11 hours ago, jcxz said: Так вроде Вы написали, что анализируете: Ну да, это я к слову... Кстати, вы не читали Дж. Ю "Архитектура процессоров Cortex-M3 и Cortex-M4"? У него целая глава посвящена hf. Тоже и в книге для Cortex-M0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 17 ноября, 2018 Опубликовано 17 ноября, 2018 · Жалоба 10 часов назад, haker_fox сказал: Кстати, вы не читали Дж. Ю "Архитектура процессоров Cortex-M3 и Cortex-M4"? У него целая глава посвящена hf. Тоже и в книге для Cortex-M0. Нет. Много лет назад сделал обработку fault-ов. С тех пор просто перетаскиваю её из проекта в проект. Сделал по даташиту на ядро. Там всего ничего регистров. С M0 не работал, только M3/M4. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 18 ноября, 2018 Опубликовано 18 ноября, 2018 · Жалоба On 2/1/2017 at 8:44 AM, ViKo said: Допустим, memcpy умеет правильно обращаться по невыровненному адресу. Или тупо байтами копирует. Но как помогает приведение указателя к указателю на выровненную структуру? От этого положение данных не меняется же. memcpy копирует в общем случае побайтно. Вроде есть реализации, где она копирует сначала в максимальной разрядности процессора, а потом, при нечетном количестве байт, докопирует побайтно. Очевидно, что реализация для M0|M0+ будет побайтная. Приведение к упакованной структуре просто порождает код, который работает побайтно. Потому компилятору и сообщают ключи типа -CortexM0, вроде того. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 18 ноября, 2018 Опубликовано 18 ноября, 2018 · Жалоба 5 часов назад, KnightIgor сказал: Очевидно, что реализация для M0|M0+ будет побайтная. Приведение к упакованной структуре просто порождает код, который работает побайтно. Из чего это очевидно? memcpy в IAR проверяет - выровнены ли на 4 оба адреса и если да, то копирует (size & -16) байт (где size - размер из аргумента функции) инструкциями LDM/STM; если адреса не выровнены или (4 <= size < 16) - копирует пословно (по 4 байта LDR/STR); и только остальное - побайтно. Ну вначале ещё немного копирует побайтно, пытаясь выровнять адреса. То же самое возможно и в M0, имхо. "Приведение к упакованной структуре" ничего не порождает, так как анализ указателей и размера происходит внутри memcpy() в runtime и memcpy ничего не знает о типе копируемых данных. И вообще не знает - структура это, или её часть или просто произвольная область памяти. Конечно некоторые компиляторы, имея данные о выравнивании или о размере копирования, могут вместо memcpy() общего вида подставлять специализированные memcpy, оптимизированные под данный случай вызова (не нужны проверки и выравнивания внутри в runtime). Для пользователя (пишущего в коде memcpy()) всё это прозрачно и копирование он может считать побайтным. Если конечно он не сделал глупостей с приведением типа аргументов memcpy() (если такие глупости могут иметь место быть, то компилятор, будучи введён в заблуждение кривым приведением типов, может подставить оптимизированные функции memcpy() вместо memcpy() общего вида - тогда и будут проблемы с выравниванием). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GeorgK 1 18 ноября, 2018 Опубликовано 18 ноября, 2018 · Жалоба Насчёт упакованной структуры - тут надо более чётко и громко сказать, что она наоборот делает объекты внутри себя невыровненными, выкидывая выравнивающие вставки. И кстати, тут по-моему не упоминался такой приём - объединять в union какой-нибудь void* или что-то вроде и указатель на требующий выравнивания тип. Тогда он будет выровнен и не появятся предупреждения компилятора о потере выравнивания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 19 ноября, 2018 Опубликовано 19 ноября, 2018 · Жалоба On 2/1/2017 at 1:22 PM, jcxz said: Вот для типов u16p8 и s16p8 (пакованный до байт беззнаковый и знаковый u16/s16): Спасибо. После допиливания (я не очень понял, как оно работает изначально, без создания объекта, хотя бы временного) получилось следующее: struct CASTtoU16 { template <typename T> CASTtoU16(T *data) : bytes((uint8_t *)data) { } uint8_t * const bytes; operator uint16_t() const { return bytes[0] | (bytes[1] << 8); } CASTtoU16 & operator =(uint32_t val) { bytes[0] = val; bytes[1] = val >> 8; return *this; } }; // example uint8_t arr[32]; CASTtoU16 {&arr[3]} = u16; uint16_t u16 = CASTtoU16 {&arr[5]}; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться