|
2 страниц
1 2 >
|
 |
Ответов
(1 - 21)
|
Sep 25 2011, 15:32
|
Группа: Новичок
Сообщений: 8
Регистрация: 25-09-11
Пользователь №: 67 366

|
Микроконтроллер Silicon Laboratories C8051F126
xdata - flash
Смотрю через вот так: printf("%d",v5); // выводится на экран устройства
Через некоторое время - не замерял, всегда оно разное, в зависимости от того, как пользователь будет пользоваться устройством - пока дойдет до этого кода, выводящего значение на экран - может пройти секунд 5-10, а может и несколько минут.
В это время МК: крутится в цикле, ждет пока юзер нажмет одну из кнопок.
|
|
|
|
|
Sep 26 2011, 02:41
|
Знающий
   
Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831

|
Цитата(Палыч @ Sep 26 2011, 03:36)  Значение переменной изменилось на минус 1. Это значение соответствует "чистой" flash. Ваш вопрос можно перефразировать: почему стирается flash типа ..., подключенная... и т.д.? Плюс к этим словам, все-таки словом xdata будет лучше называть соответствующую область RAM. А flash это память программ. Тогда уж слово "code" более подходит. Это, конечно, офтоп. По существу. Очень странно, что содержимое ячейки флэш вроде как слетает, а сама прога нет. Или поведение программы тоже меняется? или начинает сбоить? Если нет - значит собака порылась все-таки в проге и Вы что-то не договариваете. Типа v5 у Вас объявлена как char, а printf ждет int, или еще что-нибудь в этом роде.
|
|
|
|
|
Sep 26 2011, 08:09
|
Группа: Новичок
Сообщений: 8
Регистрация: 25-09-11
Пользователь №: 67 366

|
Извините, бес попутал. xdata - это конечно же оперативная память. Код // адрес, куда сохранить значение во флэше #define a_v5 0xf3a8
// во флэш-памяти code int c_v5 _at_ a_v5;
// в оперативке xdata int v5 = 2;
void WriteFlash(void) { char xdata EA_save=EA; EA=0; SFRPAGE = 0x00; FLSCL=0x21; PSCTL=1;
*((int xdata*)a_v5)=(int)v5; // тут дальше аналогичный код для других переменных... PSCTL=0; FLSCL=0x20;
EA=EA_save; }
void ReadFlash(void) { char xdata EA_save=EA; EA=0;
SFRPAGE = 0x00; FLSCL=0x21;
v5 = (int)c_v5; // <- вот в этом месте портится значение переменной v5 FLSCL=0x20; EA=EA_save; } Когда пользователь решил изменить эту переменную, он вводит значение в v5, после этого вызывается WriteFlash, пишущий это значение по определенному адресу во флэш-память. При включении прибора вызывается функция ReadFlash, копирующая из флэш в оперативку все переменные.
Сообщение отредактировал jdhfdg - Sep 26 2011, 08:10
|
|
|
|
|
Sep 26 2011, 09:35
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Из Ваших путанных объяснений непонятно: в какой момент и при каких условиях портятся данные. Судя по посту выше: при чтении переменной из flash - читается не то значение, которое туда ранее было записано. Видется 2 варианта почему так может происходить: 1. Процедура записи - не верна (тут я ничего подсказать не могу, т.к. с этим МК не работал). Но это можно проверить: записать программно во flash заранее известные данные, а затем проверить память (flash), считав её программатором и сравнить с тем, что туда писалось... 2. Обнуление переменной происходит при "заливке" программы в МК, т.к., обычно, перед программированием памяти программ производится её (памяти) очистка, а значит - стирается и область flash в которую Вы сохранили переменные.
|
|
|
|
|
Sep 26 2011, 13:51
|
Группа: Новичок
Сообщений: 8
Регистрация: 25-09-11
Пользователь №: 67 366

|
Дело в том, что остальные переменные пишутся и считываются таким же образом и проблем не возникает. Цитата записать программно во flash заранее известные данные, а затем проверить память (flash), считав её программатором и сравнить с тем, что туда писалось... Имеется программатор USB Debug Adapter (Silicon Laboratories). Подскажите, где в IDE Silicon Laboratories (или в Keil uVision) найти такую функцию?
|
|
|
|
|
Sep 26 2011, 15:06
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(jdhfdg @ Sep 26 2011, 17:51)  Дело в том, что остальные переменные пишутся и считываются таким же образом и проблем не возникает. Что же Вы это скрывали от общественности? Тогда следующая версия - ошибка (описка) с адресами: например, у другой переменной такой же адрес во flash, или "не разнесли" достаточно адреса переменных и другая переменная "наезжает" на эту... Можно временно закомментировать запись других переменных и посмотреть - не испортится ли переменная v5 ? Попутно вопросы: типы остальных переменных (с которыми "проблем не возникает") тоже int ? Есть ли массивы? В какие адреса пишутся? Цитата(jdhfdg @ Sep 26 2011, 17:51)  Имеется программатор USB Debug Adapter (Silicon Laboratories). Подскажите, где в IDE Silicon Laboratories (или в Keil uVision) найти такую функцию? Раз у Вас Debug Adapter, то, наверное, в отладчике можно "ходить" "по шагам", посмотреть состояние памяти в момент выполнения некоего кода? Можно порекомендовать воспользоваться окном Keil'а "Мемоry" (может быть, нечто подобное есть и в IDE Silicon Laboratories ?) после программной записи во flash переменных и посмотреть: что записалось? Однако, боюсь, что Keil во время отладки не отслеживает изменение памяти программ... Ну, а вдруг?
|
|
|
|
|
Sep 26 2011, 19:25
|
Группа: Новичок
Сообщений: 8
Регистрация: 25-09-11
Пользователь №: 67 366

|
чтобы переменные не наезжали друг на друга - я это первым делом проверил - все в порядке там. тут что-то по чище...
рядом стоят одни int-ы. Чуть дальше есть и float-ы, и массивы. Под них считаю - количество элементов умножить на размер типа. Размещаю всё впритык.
ходить по шагам пробовал, но толку мало. в указанном месте просто выдает не то значение, которое записывал ранее. да еще и неудобно жутко - когда идешь по шагам показывает не тот код, который сейчас выполняется, а тот в котором находится функция main. Но это отдельная история... Это в uvision. А в Silicon Laboratories дела с этим обстоят еще хуже...
Сообщение отредактировал jdhfdg - Sep 26 2011, 19:28
|
|
|
|
|
Sep 26 2011, 22:53
|
Знающий
   
Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831

|
Цитата(jdhfdg @ Sep 27 2011, 06:25)  ходить по шагам пробовал, но толку мало. в указанном месте просто выдает не то значение, которое записывал ранее. да еще и неудобно жутко - когда идешь по шагам показывает не тот код, который сейчас выполняется, а тот в котором находится функция main. Но это отдельная история... Это в uvision. А в Silicon Laboratories дела с этим обстоят еще хуже... Проходили такое. Это неправильно организован проект. Все сишные файлы должны билдиться (простите за сленг), а инклудиться только хедеры с объявлением функция, а не определением. Тогда отладка будет певеселее. По существу. Во-первых, не возникает ли сброса по записи во флэш? Смотрим в RSTSRC или как он называется в данном камне? Во-вторых, возможно все-таки, и скорее всего ошибка в проге. Попробуйте после однократной записи данных вообще запретить запись - либо залочить, либо в функции записи поставить проверку софтверного флага. Если залочите, а запись все-таки вызовется произойдет сброс по ошибке флэш. А может сперва сделать как написал выше с файлом, содержащим функцию записи, или на крайний случай временно перенести функцию в файл с main и поставить брекпоинт в функции. Тем самым отловите непреднамеренный вызов функции. UPD. Кстати, посмотрите в отладчике, что на самом деле записано в ячейке флэш когда она якобы испортилась, може не там ищем?
|
|
|
|
|
Sep 27 2011, 05:23
|
Участник

Группа: Участник
Сообщений: 25
Регистрация: 3-03-06
Пользователь №: 14 931

|
В утилите "Silabs Flash Utility" есть закладка "Get Memory". Используя Debug Adapter можно прочитать содержимое любой части памяти из микроконтроллера и записать в файл. Правда, формат записи будет дурацкий - текст в колонку, но на сайте силабса есть программка ASCII2BIN, которая превращает его в обычный бинарный код, далее - в HEX. Я этим пользовался, когда надо было зашить в контроллер точную копию программы с другого такого же.
|
|
|
|
|
Sep 27 2011, 20:23
|
Группа: Новичок
Сообщений: 8
Регистрация: 25-09-11
Пользователь №: 67 366

|
Есть функция, которая пишет данные из ОЗУ во FLASH. Если вызываю эту функцию в одном месте программы (в начале), то после этого во FLASH оказываются актуальные данные вперемешку с неправильными данными - чаще нулевые значения (или иногда старые данные, которые записывал туда неделю назад, т.е. те которые когда-то там были). Если вызываю ЭТУ ЖЕ функцию в другом месте программы - работает, пишутся актуальные данные! То есть одна и та же функция, если вызывать ее из разных частей программы, ведет себя по-разному - то работает абсолютно адекватно, то наоборот. Может где-то какие-то регистры залочены и запись не срабатывает? Может в какие-то моменты времени нельзя писать во флэш? Если вы знаете, объясните этот момент. И еще, обязательно ли записывать данные побайтно? Можно ли целиком float или int значение сразу писать, как в коде, который я показывал? Или надо обязательно разбивать на отдельные байты? Вот тут только пример для записи побайтно, а мне нужно отдельными переменными сохранять. http://www.efo.ru/doc/Silabs/Silabs.pl?2050
Сообщение отредактировал jdhfdg - Sep 27 2011, 20:27
|
|
|
|
|
Sep 27 2011, 22:33
|
Знающий
   
Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831

|
Цитата(jdhfdg @ Sep 28 2011, 07:23)  Есть функция, которая пишет данные из ОЗУ во FLASH. Если вызываю эту функцию в одном месте программы (в начале), то после этого во FLASH оказываются актуальные данные вперемешку с неправильными данными - чаще нулевые значения (или иногда старые данные, которые записывал туда неделю назад, т.е. те которые когда-то там были).
Если вызываю ЭТУ ЖЕ функцию в другом месте программы - работает, пишутся актуальные данные! То есть одна и та же функция, если вызывать ее из разных частей программы, ведет себя по-разному - то работает абсолютно адекватно, то наоборот.
Может где-то какие-то регистры залочены и запись не срабатывает? Чем дальше в лес, тем толще партизаны  . Вы флэш перед использованием стираете? Проверили причину сброса? Должна быть всегда последняя причина сброса по питанию. У Вас так? Можно в самом коде вначале определять причину сброса и зацикливаться , чтобы отловить. Может у Вас вотчдог или еще какая гадость... UPD. А для чего у Вас такая сложная функция чтения из флэш? Читать же можно гораэдо проще. Это равносильно, что вы при компиляции объявили переменную с модификатором "code". Соответсвенно просто заведите указатель на код типа: Код char code* val_ptr; //далее, например, понадобилось нам достать флоат в объявленную ранее data_float из адреса 0x7c00 val_ptr=0x7c00; data_float=*(float*)val_ptr; А в общем-то можно вообще не заводить эту пустую переменную и сделать: Код data_float=*(float*)0x7c00;
|
|
|
|
|
Sep 28 2011, 08:33
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(jdhfdg @ Sep 28 2011, 00:23)  вперемешку с неправильными данными - чаще нулевые значения Цитата(barabek @ Sep 28 2011, 02:33)  Вы флэш перед использованием стираете? А, действительно: стираете ли flash? Читаем DS: Цитата A byte location to be programmed must be erased before a new value can be written. Правильная запись во flash при перемещении процедуры записи - побочный результат "перезаливки" программы с предварительным стиранием памяти.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|