|
Чтение из флеш памяти. |
|
|
|
Nov 17 2016, 13:17
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Какая то мистика. Пробую так Код #define PFLASH_BLOCK_BASE 0x00000000U #define PSECTOR_SIZE 0x00001000U /* 4 KB size */ #define USER_PAGE 250 #define USER_PAGE_START_ADDR (PFLASH_BLOCK_BASE + (USER_PAGE * PSECTOR_SIZE))
uint8_t buff[4]; uint32_t addr = USER_PAGE_START_ADDR; memcpy(&buff, (uint8_t*)addr, 4); или так Код uint32_t I = *((uint32_t *) addr) в первом случае вылетает в эксепшен (на картинке). во втором брэкпоинт остается на месте и не двигается. я думал что нет такого адреса. но 0x00000000U + (250 * 0x00001000U) = 0xFA000 там правда непонятно что записано. ну так считался бы мусор.
Сообщение отредактировал Jenya7 - Nov 17 2016, 13:44
Эскизы прикрепленных изображений
|
|
|
|
|
 |
Ответов
|
Nov 17 2016, 14:03
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Попробуйте вместо memcpy(&buff, (uint8_t*)addr, 4); скормить ему memcpy(&buff[0], (uint8_t*)addr, 4); или memcpy(buff, (uint8_t*)addr, 4);  ps А так получается, что Вы собираетесь затереть память, где расположен указатель/имя массива.
Сообщение отредактировал k155la3 - Nov 17 2016, 14:06
|
|
|
|
|
Nov 17 2016, 14:16
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(k155la3 @ Nov 17 2016, 20:03)  Попробуйте вместо memcpy(&buff, (uint8_t*)addr, 4); скормить ему memcpy(&buff[0], (uint8_t*)addr, 4); или memcpy(buff, (uint8_t*)addr, 4);  ps А так получается, что Вы собираетесь затереть память, где расположен указатель/имя массива. работают все три метода  . сегодня компайлеры наверно идут с foolproof.  ситуация такая. может во время записи дернулось питание или что то вроде этого и в ячейках мы видим какой то мусор -- -- -- -- . но если записалось корректно то считывание проходит нормально. что же получается - если считываем битые ячейки вываливаемся в эксепшн?
|
|
|
|
|
Nov 17 2016, 16:21
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Прежде чем что-то писать/читать из флеша - нужно расставить буйки. Точнее поделить основную флешь память на две части ещё в линкере. Назначить уникальное имя для оставшейся части флеша. Создать статическую структуру с расположением в этой части флеш. Запихнуть в структуру всё что требуется, со всеми немыслимыми выкрутасами. Например это 20 копий секретной инфы, которая должна меняться при каждом важном для вас событии. Если хорошо постараться - то можно уместиться в две-три страницы. Есно структуру объединить с более простым и наглядным двойным массивом. В событии будет запись новой структуры на чистое место, или стирание страницы и записи на новое чистое место. Поиск по возрастающему номеру в записи (для каждой страницы отдельное пространство цифр, например от 1 до 10, и от 11 до 21). Проверка на ликвидность записи - по чтению копии, и сверке rcr. Битые ячейки рано или поздно появятся, это норма.
Тогда можно полностью избавится от указателей, и попаданием пальцем в небо. И главное - стабильное выполнение программы в не зависимости от уровня оптимизации.
И ещё, memcpy, если это ваша личная функция - то написана она явно не слишком аккуратно. Флеш память мк в принудительном режиме читается/пишется по 8-16-32-64 бита - у разных моделей по разному. Зависит от конкретной модели мк. А прямая запись с неродным размером приёмного регистра - просто не корректна.
|
|
|
|
|
Nov 17 2016, 16:39
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(AVI-crak @ Nov 17 2016, 22:21)  Прежде чем что-то писать/читать из флеша - нужно расставить буйки. Точнее поделить основную флешь память на две части ещё в линкере. Назначить уникальное имя для оставшейся части флеша. Создать статическую структуру с расположением в этой части флеш. Запихнуть в структуру всё что требуется, со всеми немыслимыми выкрутасами. Например это 20 копий секретной инфы, которая должна меняться при каждом важном для вас событии. Если хорошо постараться - то можно уместиться в две-три страницы. Есно структуру объединить с более простым и наглядным двойным массивом. В событии будет запись новой структуры на чистое место, или стирание страницы и записи на новое чистое место. Поиск по возрастающему номеру в записи (для каждой страницы отдельное пространство цифр, например от 1 до 10, и от 11 до 21). Проверка на ликвидность записи - по чтению копии, и сверке rcr. Битые ячейки рано или поздно появятся, это норма.
Тогда можно полностью избавится от указателей, и попаданием пальцем в небо. И главное - стабильное выполнение программы в не зависимости от уровня оптимизации.
И ещё, memcpy, если это ваша личная функция - то написана она явно не слишком аккуратно. Флеш память мк в принудительном режиме читается/пишется по 8-16-32-64 бита - у разных моделей по разному. Зависит от конкретной модели мк. А прямая запись с неродным размером приёмного регистра - просто не корректна. да но почему при чтении битых ячеек я вылетаю в эксепшен?
|
|
|
|
|
Nov 17 2016, 17:51
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Цитата(Jenya7 @ Nov 17 2016, 22:39)  да но почему при чтении битых ячеек я вылетаю в эксепшен? Я не понимаю слова "эксепшен"... Читать флешь память можно двумя способами, по прямому адресу и через мапинг. Прямой адрес флеша для st - обычно висит на 0x08000000. И читается/пишется исключительно родным для этой флеши размером посылки. Каким размером читать/писать - нужно смотреть доки на конкретный чип. Первый попавшийся пример из инета http://easystm32.ru/for-beginners/38-flash-stm32И через мапинг, с нулевого физического адреса. По этому адресу может оказаться как флеш память, так и рам память, и даже внешняя память. Всё зависит от состояния ножек boot, и регистров переадресации мапинг. В случае когда по дефолту загрузка идёт с флеша (без всяких ускорителей как M7) - то флеш становится доступной для чтения с нулевого адреса. Вот тут её можно читать как угодно, и вдоль и поперёк и по 8 бит и по 64 бита за раз - как хочется. Все эти выкрутасы обработаются системной шиной - именно она будет читать флешь память. Записать через шину не получится.
|
|
|
|
|
Nov 20 2016, 08:19
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(AVI-crak @ Nov 17 2016, 23:51)  Я не понимаю слова "эксепшен"... Читать флешь память можно двумя способами, по прямому адресу и через мапинг. Прямой адрес флеша для st - обычно висит на 0x08000000. И читается/пишется исключительно родным для этой флеши размером посылки. Каким размером читать/писать - нужно смотреть доки на конкретный чип. Первый попавшийся пример из инета http://easystm32.ru/for-beginners/38-flash-stm32И через мапинг, с нулевого физического адреса. По этому адресу может оказаться как флеш память, так и рам память, и даже внешняя память. Всё зависит от состояния ножек boot, и регистров переадресации мапинг. В случае когда по дефолту загрузка идёт с флеша (без всяких ускорителей как M7) - то флеш становится доступной для чтения с нулевого адреса. Вот тут её можно читать как угодно, и вдоль и поперёк и по 8 бит и по 64 бита за раз - как хочется. Все эти выкрутасы обработаются системной шиной - именно она будет читать флешь память. Записать через шину не получится. у меня не STM32 а Kinetis K-70. но для чтения как мне кажется это не принципиально. чтение прозрачно - просто обращение к адресу. на картинках ясно видно что при обращении к 0x000FA000 когда там -- -- -- -- -- -- -- (вторая картинка) при чтении возникает <Exeption frame> и мы попадаем в default_isr (первая картинка). но если записались нормальные данные (третья картинка) все считывается нормально. если сам факт имеет место быть то камень надо менять. не дай бог такое произойдет в полевых условиях.
Эскизы прикрепленных изображений
|
|
|
|
|
Nov 20 2016, 08:59
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Jenya7 @ Nov 20 2016, 11:19)  когда там -- -- -- -- -- -- -- Но вы же сами понимаете, что данных "-- -- -- -- -- -- --" быть не может. Таким образом отладчик вам показывает, что эта область памяти недоступна для чтения. Я не знаю, по какой причине она недоступна - это должно быть описано в документации на ваш контроллер. Возможно она просто все еще выполняет предыдущую операцию стирания или записи со стиранием. В той же документации может быть написано, что попытки обращения к памяти в эти моменты вызывают исключение (мы же на русскоязычном форуме, в конце концов). В любом случае прочитать эту документацию вам придется.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 20 2016, 11:16
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(HardEgor @ Nov 20 2016, 16:51)  Значит где-то недочитали - ведь картинку с "-- -- -- -- -- -- --" как-то получили и никто не вылетел в исключение. Возможно ваша подпрограмма чтения из флеш не обрабатывает какие-то ошибки или не читает дополнительные флаги. я перегрузил контроллер. поставил точку останова до чтения из адреса. посмортел что там по этому адресу - там (----------).запустил отладчик и на чтении получил исключение. так я мучался пол дня. потом решил переписать данные на странице и на нормально записанной странице все читается прекрасно. сам факт исключения при чтении из флеша мне кажется неприемлимым. ну подняли бы какой нибудь флаг в статус регистре и все. хотя я допускаю что это не аппаратное а программное исключение. тогда надо искать пути пресечения этого безобразия.
Сообщение отредактировал Jenya7 - Nov 20 2016, 11:19
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|