Модераторы: PILOT, ManiaK, Mazzi

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> циклический буфер переменной длины 
:(
    Опции темы
daemonaz
Дата 28.10.2010, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 160
Регистрация: 4.5.2008

Репутация: нет
Всего: нет



Цитата(xvr @  28.10.2010,  20:19 Найти цитируемый пост)
Свою область стереть нельзя?

понимаете в чем дело, модуль не знает, что его только что перепрошили, он продолжает свою работу так, как ее предшественник, откуда ему знать что только что перепрошили? Если бы весь софт я написал, то предусмотрел бы такой вариант, после перепрошивки прога должна распознать свое обновление по версиям и контрольной сумме, а потом принимает решение стирать или нет, но как реализовали мои коллеги (я их в глаза не видел, мне подсунули модуль LOG), я не знаю.

Это сообщение отредактировал(а) daemonaz - 28.10.2010, 21:21
PM MAIL   Вверх
daemonaz
Дата 28.10.2010, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 160
Регистрация: 4.5.2008

Репутация: нет
Всего: нет



Вообщем-то додумался, короче head-маркер сделать один единственным на весь буфер, а все остальные маркеры - tail маркеры, так вот чтоб записать новое сообщение, ищется head-маркер, после чего пишется сообщение, а сам маркер заменяется на tail-маркер, сообщение обрамляется head-маркером, то есть это и есть начало следующего нового сообщения, а первым хвостом будет первый найденный tail_маркер после head. Жду комментарий.   smile 
PM MAIL   Вверх
xvr
Дата 29.10.2010, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(daemonaz @  28.10.2010,  21:20 Найти цитируемый пост)
откуда ему знать что только что перепрошили?
Элементарно. В начале лога располагается специальный многобайтовый маркер, который в принципе не может встретится в этом месте в образе прошивки для МК. Обычно такой маркер можно выбрать, т.к. в начале прошивки МК обычно лежат какие то фиксированные данные,  типа векторов прерывания или чего то похожего. И у этих данных вполне регулярная структура.
Если модуль логирования не находит этого маркера, он стирает всю область и пишет маркер (собственно сам маркер после этого не меняется)

Цитата(daemonaz @  28.10.2010,  23:06 Найти цитируемый пост)
а сам маркер заменяется на tail-маркер,
Это подразумевает 2х кратное переписывание каждой ячейки EEPROM с маркером. Не очень хорошо.

Кроме того, проблема с неинициализированным после перепрошивки буфером не решается - в нем вообще никаких маркеров не будет


PM MAIL   Вверх
Alexeis
Дата 29.10.2010, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: нет
Всего: 459



Цитата(xvr @  29.10.2010,  12:30 Найти цитируемый пост)
Элементарно. В начале лога располагается специальный многобайтовый маркер, который в принципе не может встретится в этом месте в образе прошивки для МК.

  Я у себя использовал такой 0xAAAAAAAA smile . Бинарно это выглядит как заборчик 101010101010101... . Специально такого не будет что 32 бита заборчика и глазами если что легко увидеть в дампе.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Mazzi
Дата 29.10.2010, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Правильный
**


Профиль
Группа: Комодератор
Сообщений: 825
Регистрация: 3.4.2003

Репутация: 9
Всего: 21



Код

#define ADDR_BEG 0x0000
#define ADDR_END 0x7FFF

int16 p_beg, p_end;
eeprom int8 array[ADDR_END-ADDR_BEG];

// функция добавления данных в EEPROM
void add_byte( int8 dat ) {
        array[p_end++] = dat;
        if ( p_end >= ADDR_END ) p_end = ADDR_BEG;
}
// функция извлечения данных из EEPROM
int8 get_byte( void ) {
int8 res;
       res = array[p_beg++];
       if ( p_beg >= ADDR_END ) p_beg = ADDR_BEG;
       return res;
}
// функция проверки наличия данных в памяти
int8 is_fill( void ) {
       if ( p_beg != p_end ) return 1; // данные есть
       else return 0; // данных нет
}



--------------------
Мне нужны помощники.
PM MAIL WWW   Вверх
xvr
Дата 29.10.2010, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(Mazzi @ 29.10.2010,  17:03)
Код

#define ADDR_BEG 0x0000
#define ADDR_END 0x7FFF

int16 p_beg, p_end;
eeprom int8 array[ADDR_END-ADDR_BEG];
...


Осталось самая малость - найти p_beg, p_end; при включении МК, причем в EEPROM их записывать нельзя  smile 
PM MAIL   Вверх
Mazzi
Дата 29.10.2010, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Правильный
**


Профиль
Группа: Комодератор
Сообщений: 825
Регистрация: 3.4.2003

Репутация: 9
Всего: 21



Цитата

Осталось самая малость - найти p_beg, p_end; при включении МК, причем в EEPROM их записывать нельзя
...
Почему нельзя?
Код

#define ADDR_P_BEG 0x0000
#define ADDR_P_END 0x0002
#define ADDR_BEG 0x0004
#define ADDR_END 0x7FFF
int16 p_beg, p_end;
eeprom int8 array[ADDR_END-ADDR_BEG];

Затем в начале кода читаем сохранённые значения, а в конце функций обращения к памяти перезаписываем.


--------------------
Мне нужны помощники.
PM MAIL WWW   Вверх
xvr
Дата 30.10.2010, 09:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(Mazzi @  29.10.2010,  18:32 Найти цитируемый пост)
Почему нельзя?
Потому что у него NAND FLASH (будет), который необходимо записывать/перезаписывать последовательно (для достижения заявленного ресурса перезаписей). Сохранить указатели в EEPROM я ему посоветовал еще в 3м сообщении (если есть EEPROM с достаточным ресурсом перезаписей)


PM MAIL   Вверх
daemonaz
Дата 30.10.2010, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 160
Регистрация: 4.5.2008

Репутация: нет
Всего: нет



да и еще нужно писать сообщения переменной длины, не забывайте! smile 
PM MAIL   Вверх
daemonaz
Дата 30.10.2010, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 160
Регистрация: 4.5.2008

Репутация: нет
Всего: нет



Вообщем-то я понял так, в начале лога пишется длинный маркер, по которому мы определяем, была ли перепрошивка или нет, если такой маркер присуствует, то ишем указатели, иначе стираем всю область памяти, и cтолбим этот же маркер. Далее хотим мы записать новое сообщение, по предложению уважаемого xvr, вводим  ESC-последовательность, чтобы выделить начало и конец сообщения, у каждого сообщения будет свой ID, по ID будем определять где head и где tail. При включении МК ишется разница между ID,   если она больше 1, то сообщение с малым ID - head, а с большим ID - tail. теперь заполнили всю область LOG, нужно записать новое сообщение, вот здесь как быть? Либо весь блок Flash отдать под одно сообщение, что слишком жирно, или каждый раз нужно переписывать этот блок, либо стереть этот блок и начинаем писать заново? Мой моск разваливается..  smile 
PM MAIL   Вверх
Mazzi
Дата 30.10.2010, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Правильный
**


Профиль
Группа: Комодератор
Сообщений: 825
Регистрация: 3.4.2003

Репутация: 9
Всего: 21



Нужно два разных маркера в начале всех записей и в конце. Если записей нет, то в памяти только маркеры. 


--------------------
Мне нужны помощники.
PM MAIL WWW   Вверх
xvr
Дата 30.10.2010, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Mazzi абсолютно прав - маркеров нужно 2 (что бы корректно определить целые записи). ID должен быть достаточного размера, что бы полностью заполненный FLASH при минимальной длине каждой записи не вызвал переполнение ID (причем нужен как минимум 2х кратный запас).
Записи пишутся во FLASH по кольцу (как в исходнике от Mazzi), при переполнении новые записи начинают затирать старые.
При старте ищутся первая и последняя целая запись (должны присутствовать оба маркера), и извлекаются их ID. Затем ID сравниваются на больше-меньше (с учетом возможного переполнения, т.е. если старшие биты у них разные, то произошло переполнение и ID с нулевым старшим битом считается больше, чем ID с единичным старшим битом). 
Собственно все - запись с большим ID будет головой (писать надо сразу после нее), запись стартует со следующего ID. 
Запись с меньшим ID становится указателем чтения.

PM MAIL   Вверх
daemonaz
Дата 31.10.2010, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 160
Регистрация: 4.5.2008

Репутация: нет
Всего: нет



это конечно не по теме, не хочу открывать новую ветку.. Вопрос, как вычислить кратность некоторому числу без деления с остатками?
например, если 16 делится на 8, используется 16%8=0, не делится 15%8!=0, как это сделать без деления?
второе,  как вычислить наибольшее ближайшее данному числу кратное некому числу без цикла? Например, у нас число 13, он не делится на 8, доводим его 16. 
Я делаю так..

 
Код


c = 13;
while ((c%8)!=0){
  c++;
}



Есть ли быстрый и эффективный способ?


PM MAIL   Вверх
xvr
Дата 31.10.2010, 17:48 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(daemonaz @  31.10.2010,  16:57 Найти цитируемый пост)
 Вопрос, как вычислить кратность некоторому числу без деления с остатками?
Если это 'некоторое число' - степень двойки, то элементарно: (x&(N-1))==0 - число x кратно N

Цитата(daemonaz @  31.10.2010,  16:57 Найти цитируемый пост)
как вычислить наибольшее ближайшее данному числу кратное некому числу без цикла?
x - число, N - выравнивание (должно быть степень двойки)
Код

x=(x+N-1)&~(N-1);

В общем случае (если N НЕ степень двойки)
Код

x=(x+N-1)/N*N;
или
Код

int y=x%N;
if (y) x+=N-y;


PM MAIL   Вверх
daemonaz
Дата 31.10.2010, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 160
Регистрация: 4.5.2008

Репутация: нет
Всего: нет



xvr, огромное спасибо! smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.0589 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.