|
Сохранение важных переменных в EEPROM при потере питяния |
|
|
|
Feb 9 2012, 04:50
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 20-11-09
Из: Ставрополь
Пользователь №: 53 756

|
Цитата(zombi @ Feb 8 2012, 23:22)  Как часто поступает команда стоп?
Как Вы определяете что движение закончено? Это протокол обмена Pelco-D. Команда стоп подается от хоста. Не чаще думаю, чем 1 раз в сек. Это если ручное управление (или джойстик). А если подаются команды типа переместиться на столько-то шагов в таком-то направлении, то девайс есесно сам останавливает себя. А определять, когда движение закончено помогают концевые оптодатчики. При начальной инициализации привод перемещается от крайней до крайней позиции, передает максимальные координаты хосту (по запросу). Если движение происходит без пропуска шагов, то энкодеры можно и не ставить. А если уж пропуск случится, то повторная калибровка в помощь.
|
|
|
|
|
Feb 9 2012, 11:56
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 20-11-09
Из: Ставрополь
Пользователь №: 53 756

|
Цитата(demaven @ Feb 9 2012, 13:04)  в одной из работ потребовалось сохранять небыстро меняющуюся информацию при пропадании питания.... В нашем проекте в процессе работы не используется еепром для сохранения такого рода инфы, исключая начальную (или по запросу от хоста) инициализациюустройства и сохранении значений калибровок датчиков, максимальных и текущих координат. Цитата как Вы определяете что девайс закончил выполнение последней команды и можно посылать новую? считаю количество шагов, на которое переместился привод: таймер работает в режиме СТС. регистр compare загружается соответствующим расчетным значением. в прерывании происходит команда step драйверу привода и соответственно счетчик шагов в инкремент. как досчитал до значения переданного в команде так стоп. вот вроде пояснил. если чего, спрашивайте
|
|
|
|
|
Feb 19 2012, 04:27
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(demaven @ Feb 9 2012, 11:04)  видно, что только в одном случае нельзя восстановить новую информацию, но сохраняется старая. Зачем тогда 4 копии, когда тот же функционал можно получить и с двумя? (нарисуйте диаграмму процесса записи 4 ячеек во времени, поставьте сбой питания в любой момент времени этого процесса, отбросте две самые последние записи, - в результате получилось то же самое что и у вас сейчас: если сбой питания произошел в процессе записи __самой первой ячейки__, то последняя запись потеряется, но останется предыдущая.
|
|
|
|
|
Feb 27 2012, 14:35
|
Частый гость
 
Группа: Свой
Сообщений: 113
Регистрация: 25-10-07
Из: Краснодар
Пользователь №: 31 725

|
А что вам мешает защищать ваши ячейки контрольной суммой? Например так: CODE #include "crc.h" #include "eeprom.h"
//****************************************************************************** // Функция сохраняет данные в еепром с добавлением 2 байт CRC //****************************************************************************** bool SaveBlock(unsigned short Address, char* Data, unsigned short Size) { char Ch; unsigned short Crc = 0xFFFF; for (unsigned short Index = 0; Index < Size; Index++) { Ch = Data[Index]; __EEPUT(Address + Index, Ch); Crc = AddCrc16(Ch, Crc); } __EEPUT(Address + Size, (unsigned char)Crc); __EEPUT(Address + Size + 1, (unsigned char)(Crc >> 8)); return true; }
//****************************************************************************** // Функция читает данные из еепром с контролем 2 байт CRC //****************************************************************************** bool LoadBlock(unsigned short Address, char* Data, unsigned short Size) { char Ch; unsigned short Crc = 0xFFFF; for (unsigned short Index = 0; Index < Size; Index++) { __EEGET(Ch, Address + Index); Data[Index] = Ch; Crc = AddCrc16(Ch, Crc); } __EEGET(Ch, Address + Size); Crc = AddCrc16(Ch, Crc); __EEGET(Ch, Address + Size + 1); Crc = AddCrc16(Ch, Crc); return Crc ? false : true; }
xSemaphoreHandle EepromLockMutex = NULL;
//****************************************************************************** // Заблокировать интерфейс //****************************************************************************** void EepromLock() { portENTER_CRITICAL(); if(EepromLockMutex == NULL) EepromLockMutex = xSemaphoreCreateMutex(); portEXIT_CRITICAL(); xSemaphoreTake(EepromLockMutex, portMAX_DELAY); }
//****************************************************************************** // Разблокировать интерфейс //****************************************************************************** void EepromUnlock() { xSemaphoreGive(EepromLockMutex); }
//****************************************************************************** // Функция загружает конфигурацию из EEPROM в случае успеха возвращает true //****************************************************************************** bool EepromLoadConfig(USHORT Offset, void* Config, unsigned short Size) { bool Ret = true; Offset = (Offset + 2) * 2; EepromLock(); if (!LoadBlock(Offset + 0, Config, Size)) if (!LoadBlock(Offset + Size + 2, Config, Size)) Ret = false; EepromUnlock(); return Ret; }
//****************************************************************************** // Функция сохраняет конфигурацию в EEPROM в случае успеха возвращает true //****************************************************************************** bool EepromSaveConfig(USHORT Offset, void* Config, unsigned short Size) { Offset = (Offset + 2) * 2; EepromLock(); SaveBlock(Offset + 0, Config, Size); SaveBlock(Offset + Size + 2, Config, Size); EepromUnlock(); return true; } Функции EepromLock/EepromUnlock и расчет смещения для нескольких записей можно удалить. Функцию для расчета crc добавить по вкусу.
Сообщение отредактировал IgorKossak - Feb 27 2012, 14:37
Причина редактирования: [codebox]
|
|
|
|
|
Feb 27 2012, 14:39
|

Гуру
     
Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106

|
Цитата(demaven @ Feb 27 2012, 16:49)  с двумя местами сохранения никак не получается. ячейки неоднобайтовые Если ячейки неоднобайтовые я называл бы их не ячейками а блоками... И вполне можно обойтись всего двумя одинаковыми блоками если в каждый добавить ОДНОБАЙТОВЫЙ флаг (ноль/не ноль) достоверности блока. P.S. Без всяких CRC.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|