реклама на сайте
подробности

 
 
> Самопроизвольное изменение значения переменной
jdhfdg
сообщение Sep 25 2011, 12:44
Сообщение #1





Группа: Новичок
Сообщений: 8
Регистрация: 25-09-11
Пользователь №: 67 366



Я объявил глобальную переменную в области xdata и инициализировал ее значением 2.
После инициализации проверил - все в порядке, там записано число 2.
Через некоторое время снова проверил ее значение - оно оказалось -1.
В коде присвоения к этой переменной нигде больше нет.

Тогда как такое возможно?
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 21)
Палыч
сообщение Sep 25 2011, 13:40
Сообщение #2


Гуру
******

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



Цитата(jdhfdg @ Sep 25 2011, 16:44) *
Тогда как такое возможно?

А, Вы - что? Считаете этот форум - форумом телепатов?

Какой МК? Область xdata как физически реализована? Где и как смотрите? "Через некоторое время" - это сколько? Что в это время МК делал?
Go to the top of the page
 
+Quote Post
jdhfdg
сообщение Sep 25 2011, 15:32
Сообщение #3





Группа: Новичок
Сообщений: 8
Регистрация: 25-09-11
Пользователь №: 67 366



Микроконтроллер Silicon Laboratories C8051F126

xdata - flash

Смотрю через вот так:
printf("%d",v5); // выводится на экран устройства

Через некоторое время - не замерял, всегда оно разное, в зависимости от того, как пользователь будет пользоваться устройством - пока дойдет до этого кода, выводящего значение на экран - может пройти секунд 5-10, а может и несколько минут.

В это время МК: крутится в цикле, ждет пока юзер нажмет одну из кнопок.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 25 2011, 16:36
Сообщение #4


Гуру
******

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



Цитата(jdhfdg @ Sep 25 2011, 19:32) *
xdata - flash

Значение переменной изменилось на минус 1. Это значение соответствует "чистой" flash. Ваш вопрос можно перефразировать: почему стирается flash типа ..., подключенная... и т.д.?

Как вариант: Ваше устройство подключено к плохому источнику питания.
Go to the top of the page
 
+Quote Post
barabek
сообщение Sep 26 2011, 02:41
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831



Цитата(Палыч @ Sep 26 2011, 03:36) *
Значение переменной изменилось на минус 1. Это значение соответствует "чистой" flash. Ваш вопрос можно перефразировать: почему стирается flash типа ..., подключенная... и т.д.?


Плюс к этим словам, все-таки словом xdata будет лучше называть соответствующую область RAM. А flash это память программ. Тогда уж слово "code" более подходит. Это, конечно, офтоп.


По существу. Очень странно, что содержимое ячейки флэш вроде как слетает, а сама прога нет. Или поведение программы тоже меняется? или начинает сбоить? Если нет - значит собака порылась все-таки в проге и Вы что-то не договариваете. Типа v5 у Вас объявлена как char, а printf ждет int, или еще что-нибудь в этом роде.

Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 26 2011, 05:22
Сообщение #6


Гуру
******

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



Цитата(barabek @ Sep 26 2011, 06:41) *
Очень странно, что содержимое ячейки флэш вроде как слетает, а сама прога нет.

Вероятнее всего, что МК и flash (на которой xdata) - это две разные м/с, возможно даже - разных производителей и выполнены по разным производственным процессам. Поэтому - ничего странного нет.

P.S. Поскольку в этой flash, вероятно, ничего кроме данных не содержится, то и "обзывать" её словом "code" как-то некрасиво...
Go to the top of the page
 
+Quote Post
barabek
сообщение Sep 26 2011, 06:15
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831



Цитата(Палыч @ Sep 26 2011, 16:22) *
P.S. Поскольку в этой flash, вероятно, ничего кроме данных не содержится, то и "обзывать" её словом "code" как-то некрасиво...

Ах вот оно что. Если так, то да, Вы правы.А у меня почему-то сложилось мнение, что речь идет о внутренней памяти. Про отдельные м/с не подумал. Пусть ТС внесет больше ясности.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 26 2011, 06:27
Сообщение #8


Гуру
******

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



Цитата(barabek @ Sep 26 2011, 10:15) *
Про отдельные м/с не подумал. Пусть ТС внесет больше ясности.

Ещё не понятно: каким образом во flash (xdata) попало "начальное" значение 2 ? ТС эту память программирует во время "заливки" программы в МК?
Go to the top of the page
 
+Quote Post
jdhfdg
сообщение Sep 26 2011, 08:09
Сообщение #9





Группа: Новичок
Сообщений: 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
Go to the top of the page
 
+Quote Post
ARV
сообщение Sep 26 2011, 08:11
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



если я не ошибаюсь, то xdata - это "дополнительное" пространство ОЗУ для MCS51-семейства, ни о каком flash речь идти не может. flash - это code


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Sep 26 2011, 08:28
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Функция записи во флеш не работает из флеш.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 26 2011, 09:35
Сообщение #12


Гуру
******

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



Из Ваших путанных объяснений непонятно: в какой момент и при каких условиях портятся данные.
Судя по посту выше: при чтении переменной из flash - читается не то значение, которое туда ранее было записано. Видется 2 варианта почему так может происходить:
1. Процедура записи - не верна (тут я ничего подсказать не могу, т.к. с этим МК не работал). Но это можно проверить: записать программно во flash заранее известные данные, а затем проверить память (flash), считав её программатором и сравнить с тем, что туда писалось...
2. Обнуление переменной происходит при "заливке" программы в МК, т.к., обычно, перед программированием памяти программ производится её (памяти) очистка, а значит - стирается и область flash в которую Вы сохранили переменные.
Go to the top of the page
 
+Quote Post
jdhfdg
сообщение Sep 26 2011, 13:51
Сообщение #13





Группа: Новичок
Сообщений: 8
Регистрация: 25-09-11
Пользователь №: 67 366



Дело в том, что остальные переменные пишутся и считываются таким же образом и проблем не возникает.

Цитата
записать программно во flash заранее известные данные, а затем проверить память (flash), считав её программатором и сравнить с тем, что туда писалось...


Имеется программатор USB Debug Adapter (Silicon Laboratories).
Подскажите, где в IDE Silicon Laboratories (или в Keil uVision) найти такую функцию?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 26 2011, 15:06
Сообщение #14


Гуру
******

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



Цитата(jdhfdg @ Sep 26 2011, 17:51) *
Дело в том, что остальные переменные пишутся и считываются таким же образом и проблем не возникает.


Что же Вы это скрывали от общественности? rolleyes.gif
Тогда следующая версия - ошибка (описка) с адресами: например, у другой переменной такой же адрес во 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 во время отладки не отслеживает изменение памяти программ... Ну, а вдруг?
Go to the top of the page
 
+Quote Post
jdhfdg
сообщение Sep 26 2011, 19:25
Сообщение #15





Группа: Новичок
Сообщений: 8
Регистрация: 25-09-11
Пользователь №: 67 366



чтобы переменные не наезжали друг на друга - я это первым делом проверил - все в порядке там.
тут что-то по чище...

рядом стоят одни int-ы. Чуть дальше есть и float-ы, и массивы.
Под них считаю - количество элементов умножить на размер типа. Размещаю всё впритык.

ходить по шагам пробовал, но толку мало.
в указанном месте просто выдает не то значение, которое записывал ранее.
да еще и неудобно жутко - когда идешь по шагам показывает не тот код, который сейчас выполняется, а тот в котором находится функция main. Но это отдельная история... Это в uvision. А в Silicon Laboratories дела с этим обстоят еще хуже...

Сообщение отредактировал jdhfdg - Sep 26 2011, 19:28
Go to the top of the page
 
+Quote Post
barabek
сообщение Sep 26 2011, 22:53
Сообщение #16


Знающий
****

Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831



Цитата(jdhfdg @ Sep 27 2011, 06:25) *
ходить по шагам пробовал, но толку мало.
в указанном месте просто выдает не то значение, которое записывал ранее.
да еще и неудобно жутко - когда идешь по шагам показывает не тот код, который сейчас выполняется, а тот в котором находится функция main. Но это отдельная история... Это в uvision. А в Silicon Laboratories дела с этим обстоят еще хуже...


Проходили такое. Это неправильно организован проект. Все сишные файлы должны билдиться (простите за сленг), а инклудиться только хедеры с объявлением функция, а не определением. Тогда отладка будет певеселее.


По существу. Во-первых, не возникает ли сброса по записи во флэш? Смотрим в RSTSRC или как он называется в данном камне?

Во-вторых, возможно все-таки, и скорее всего ошибка в проге. Попробуйте после однократной записи данных вообще запретить запись - либо залочить, либо в функции записи поставить проверку софтверного флага. Если залочите, а запись все-таки вызовется произойдет сброс по ошибке флэш.

А может сперва сделать как написал выше с файлом, содержащим функцию записи, или на крайний случай временно перенести функцию в файл с main и поставить брекпоинт в функции. Тем самым отловите непреднамеренный вызов функции.

UPD. Кстати, посмотрите в отладчике, что на самом деле записано в ячейке флэш когда она якобы испортилась, може не там ищем?
Go to the top of the page
 
+Quote Post
Shandy
сообщение Sep 27 2011, 05:23
Сообщение #17


Участник
*

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



В утилите "Silabs Flash Utility" есть закладка "Get Memory". Используя Debug Adapter можно прочитать содержимое любой части памяти
из микроконтроллера и записать в файл.
Правда, формат записи будет дурацкий - текст в колонку, но на сайте силабса есть программка ASCII2BIN, которая превращает его
в обычный бинарный код, далее - в HEX.
Я этим пользовался, когда надо было зашить в контроллер точную копию программы с другого такого же.
Go to the top of the page
 
+Quote Post
barabek
сообщение Sep 27 2011, 10:38
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831



Цитата(Shandy @ Sep 27 2011, 16:23) *
В утилите "Silabs Flash Utility" есть закладка "Get Memory". Используя Debug Adapter можно прочитать содержимое


Это несколько не то, ТС хочет все делать во время отладки. И это разумно, тем более содержимое флэш можно проверять и даже изменять на лету. Для того чтобы изменить и обновить содержимое используется кнопочка "туда-сюда" wink.gif в silabs IDE


Go to the top of the page
 
+Quote Post
jdhfdg
сообщение Sep 27 2011, 20:23
Сообщение #19





Группа: Новичок
Сообщений: 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
Go to the top of the page
 
+Quote Post
barabek
сообщение Sep 27 2011, 22:33
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831



Цитата(jdhfdg @ Sep 28 2011, 07:23) *
Есть функция, которая пишет данные из ОЗУ во FLASH.
Если вызываю эту функцию в одном месте программы (в начале), то после этого во FLASH оказываются актуальные данные вперемешку с неправильными данными - чаще нулевые значения (или иногда старые данные, которые записывал туда неделю назад, т.е. те которые когда-то там были).

Если вызываю ЭТУ ЖЕ функцию в другом месте программы - работает, пишутся актуальные данные!
То есть одна и та же функция, если вызывать ее из разных частей программы, ведет себя по-разному - то работает абсолютно адекватно, то наоборот.

Может где-то какие-то регистры залочены и запись не срабатывает?

Чем дальше в лес, тем толще партизаны sm.gif. Вы флэш перед использованием стираете? Проверили причину сброса? Должна быть всегда последняя причина сброса по питанию. У Вас так? Можно в самом коде вначале определять причину сброса и зацикливаться , чтобы отловить. Может у Вас вотчдог или еще какая гадость...

UPD. А для чего у Вас такая сложная функция чтения из флэш? Читать же можно гораэдо проще. Это равносильно, что вы при компиляции объявили переменную с модификатором "code". Соответсвенно просто заведите указатель на код типа:
Код
    char code* val_ptr;
//далее, например, понадобилось нам достать флоат в объявленную ранее data_float из адреса 0x7c00
    val_ptr=0x7c00;
    data_float=*(float*)val_ptr;

А в общем-то можно вообще не заводить эту пустую переменную и сделать:
Код
data_float=*(float*)0x7c00;

Go to the top of the page
 
+Quote Post
редактор
сообщение Sep 28 2011, 07:46
Сообщение #21


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Уточнение - какая модель памяти используется, если с банками, то возможно не переключаете банк памяти при чтении (да и при записи тоже наверное). Поэтому из одного места читается правильно, а из другого нет. Если на кристалле флеши дох..., то все страницы кроме 1-й расположены по адресам выше 0x7FFF и переключаются в соотвествующем регистре.
Тогда (возможно) имется Ж старт программы выбран банк 1, чтение правильно.
Работа программы , смена банка памяти компилятором (для банковской модели нормальное явление), чтение паямти и ахинея полная.
Если не это, то косяк в программе.


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 28 2011, 08:33
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 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 при перемещении процедуры записи - побочный результат "перезаливки" программы с предварительным стиранием памяти.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 18:59
Рейтинг@Mail.ru


Страница сгенерированна за 0.01495 секунд с 7
ELECTRONIX ©2004-2016