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

Поиск:

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


Бывалый
*


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

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



Мне дали задание для микроконтроллера (не важен какой, главное, алгоритм) написать циклический буфер переменной длины, равномерно распределенный по всей памяти (NAND Flash или EEPROM), чтоб исключить перезапись в одну и ту же область памяти из за их ограничения числа записи-стирания. Там будут храниться сообщения передаваемые куда-то, новые сообщения по мере переполнения буфера затирают старые, при включения питания микроконтроллера нужно восстановить указатели на начало и конец рулона. Приходит мысль об использовании маркера и ID ячейки, больше ничего придумать не смог.. Нужен совет.. Код только на СИ, допускается использование библиотечных функции тип printf, безо всякого malloc или alloc. Спасибо. 
PM MAIL   Вверх
Bugmaker
Дата 28.10.2010, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Не до конца понял что надо, но вроде бу тут уместно использование связанных списков.
Извиняюсь, если ерунду сказал. Не до конца понял что требуется...
PM MAIL   Вверх
xvr
Дата 28.10.2010, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Если есть EEPROM с большим ресурсом, то смещения начала и конца буфера можно хранить в специально отведенных для этого ячейках EEPROM'а. (Лучше в 2х копиях с контрольной суммой, что бы можно было отловить случаю выключения питания при их записи).
Если EEPROM'а нет, то можно признаки начала и конца буфера писать прямо в самом буфере в виде специальных байтов (1 спец. в начале, 2й - в конце). Что бы эти байты не встречались внутри буфера нужно их экранировать 3м специальным байтом (писать в виде 2х байтовой ESC последовательности).
При старте контролера сканировать FLASH и искать маркеры.

Кстати, сделать совсем независимым от типа применяемого FLASH не получится - у каждого FLASH есть свои требования по размерам записываемого и стираемого блока

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


Амеба
Group Icon


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

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



Цитата(daemonaz @  28.10.2010,  01:12 Найти цитируемый пост)
при включения питания микроконтроллера нужно восстановить указатели на начало и конец рулона.

  Добавить признак того что ячейка была удалена (всего 1 бит). Также важно чтобы число ячеек в одном стираемом блоке было целым. Сначала делает бинарный поиск начала, затем конца циклического буфера. Еще такой момент, нужно знать при стирании чего записывается в ячейки нули или единицы. Если нули то признак стирания бит 1, если единицы, то 0.


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

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

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


Эксперт
****


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

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



Цитата(Alexeis @  28.10.2010,  11:06 Найти цитируемый пост)
 Добавить признак того что ячейка была удалена (всего 1 бит). 
Поменять 1 бит в NAND FLASH может не получиться (только стерев весь блок).
И вообще задача СИЛЬНО зависит от геометрии и способа записи FLASH'а. Например, если FLASH может записываться только блоками, имеет смысл сделать в начале каждого блока монотонно увеличивающийся счетчик (битов так на 32). Этого должно хватить на полное восстановление всех указателей (записи и чтения)


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


Амеба
Group Icon


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

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



Цитата(xvr @  28.10.2010,  12:16 Найти цитируемый пост)
Поменять 1 бит в NAND FLASH может не получиться (только стерев весь блок).

  А ну да, значит нужно 2 бита. Первый для определения что блок использовался, второй, что блок стерт. Пустая страница будет иметь оба бита сброшены как после стирания. После записи туда данных первый бит переключаем, после освобождения блока переключаем второй бит. Т.о. Можно отличать блоки.

Добавлено через 4 минуты и 34 секунды
Цитата(xvr @  28.10.2010,  12:16 Найти цитируемый пост)
Поменять 1 бит в NAND FLASH может не получиться (только стерев весь блок).

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


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

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

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


Бывалый
*


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

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



Цитата(xvr @  28.10.2010,  10:35 Найти цитируемый пост)
Если есть EEPROM с большим ресурсом, то смещения начала и конца буфера можно хранить в специально отведенных для этого ячейках EEPROM'а. (Лучше в 2х копиях с контрольной суммой, что бы можно было отловить случаю выключения питания при их записи).

Я на эту тему думал, а что если МК не успел записать указатели начала и конца в момент выключения питания, в EEPROM долго пишется как горячие эстонские пааарни, это отпадает.  smile 

Цитата(xvr @  28.10.2010,  10:35 Найти цитируемый пост)

Если EEPROM'а нет, то можно признаки начала и конца буфера писать прямо в самом буфере в виде специальных байтов (1 спец. в начале, 2й - в конце). Что бы эти байты не встречались внутри буфера нужно их экранировать 3м специальным байтом (писать в виде 2х байтовой ESC последовательности).
При старте контролера сканировать FLASH и искать маркеры.

Дело в том, что храниться будет и в текстовом, и двоичном виде, то есть это лог-сообщение состоящее из ntp-счетчика времени и текста лога, поэтому замена одного байта двумя распухнет буфер, мне же надо как можно больше лог-сообщении запихнуть в буфер, я тоже думал над этим, ну это на крайняк..  Такой способ наподобие протокола SLIP работает хорошо с текстом, где замен управляющих символов минимально.

Добавлено через 14 минут и 42 секунды
Есть предложение, прокомментируйте плиз..
Начало сообщения - маркер, пусть будет 0xAA55, конец - тоже маркер 0xBB66, внутри Id который позволит нам выявить где начало и конец, то есть например текущее сообщение имеет ID=3, а следующее ID = 4, пропускаем, затем идет ID=7, значит сообщение ID=4 - конец рулона, а с ID=7 начало рулона.. Когда происходит затирание новыми старых сообщений, мы ищем следующий маркер и делаем его хвостом. И еще один момент, эта область памяти используется для перепрошивки, поэтому там может оказаться мусор. Неужели нет готовых решений? 

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


Амеба
Group Icon


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

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



Цитата(daemonaz @  28.10.2010,  13:19 Найти цитируемый пост)
Неужели нет готовых решений? 

  На счет готовых лучше спрашивать тут http://forum.vingrad.ru/forum/tech-control...rogramming.html .


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

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

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


Бывалый
*


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

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



Мне дали задание для микроконтроллера (не важен какой, главное, алгоритм) написать циклический буфер переменной длины, равномерно распределенный по всей памяти (NAND Flash или EEPROM), чтоб исключить перезапись в одну и ту же область памяти из за их ограничения циклов записи-стирания. Там будут храниться сообщения передаваемые куда-то, новые сообщения по мере переполнения буфера затирают старые, при включения питания микроконтроллера нужно восстановить указатели на начало и конец рулона. Приходит мысль об использовании маркера и ID ячейки, больше ничего придумать не смог.. Нужен совет и рекомендации.. Код только на СИ, допускается использование библиотечных функции тип printf, безо всякого malloc или alloc. Если есть готовые решения, буду благодарен.. Спасибо.  
PM MAIL   Вверх
xvr
Дата 28.10.2010, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Alexeis @  28.10.2010,  11:30 Найти цитируемый пост)
Ты ведь можешь прочитать слово, изменить бит и записать назад слово или двойное слово.
Можно конечно, но у NAND FLASH есть еще одна особенность - ее рекомендуют записывать последовательно, т.е. не перезаписывая один и тот же блок по 2 раза подряд. Иначе ее ресурс упадет  smile 


Цитата(daemonaz @  28.10.2010,  12:19 Найти цитируемый пост)
поэтому замена одного байта двумя распухнет буфер,
Ну он же не каждый байт будет двумя делать


Цитата(daemonaz @  28.10.2010,  12:19 Найти цитируемый пост)
Начало сообщения - маркер, пусть будет 0xAA55, конец - тоже маркер 0xBB66, 
В таком случае эти последовательности внутри буфера так же придется ESC'апить. Т.е. ровно то, что я предлагал (только я предлагал маркеры одно байтовые)


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


Амеба
Group Icon


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

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



Цитата(xvr @  28.10.2010,  17:39 Найти цитируемый пост)
ее рекомендуют записывать последовательно, т.е. не перезаписывая один и тот же блок по 2 раза подряд

  Может имелось ввиду 2 раза со стиранием? Без стирания не должно быть проблем.


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

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

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


Бывалый
*


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

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



Цитата(xvr @  28.10.2010,  16:39 Найти цитируемый пост)
В таком случае эти последовательности внутри буфера так же придется ESC'апить. Т.е. ровно то, что я предлагал (только я предлагал маркеры одно байтовые)

Ну хорошо, перепрошили мы новую прошивку, перезапустили МК, при инициализации он видит на этом месте мусор, как быть теперь?
Маркеры скорее всего надо брать не однобайтовые, и даже не двухбайтовый, чтобы исключить вероятность совпадения мусорных байтов с маркером.


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


Эксперт
****


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

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



Цитата(daemonaz @  28.10.2010,  17:13 Найти цитируемый пост)
Ну хорошо, перепрошили мы новую прошивку, перезапустили МК, при инициализации он видит на этом месте мусор, как быть теперь?
Там не может быть мусора, который совпадет с маркерными байтами, т.к. таких байтов в теле предыдущих записей быть не может (они esc'апятся), а FLASH при стирании никогда не заполняется мусором.

Пардон, не обратил внимания, что у вас в этом месте может быть прошивка МК. Это лечится элементарно - надо обеспечить стирание FLASH после перепрошивки и до переиспользования ее под логгер.

И вообще, у вас FLASH блочная, или она умеет писаться побайтно? (в последнее верится с трудом)
Если первое, то вам надо ориентироваться именно на блочную структуру записи (см мое 2е сообщение назад)

Добавлено @ 17:51
Цитата(Alexeis @  28.10.2010,  17:03 Найти цитируемый пост)
Без стирания не должно быть проблем.
Могут быть. У разных производителей свои заскоки  smile 


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


Бывалый
*


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

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



да нет, пока у меня стоит EEPROM, так что гуляем..  smile  Но потом планируется заменить на флеш, вот здеся и будет геморой с блоками..
Для начала мне нужно выбрать стратегию..  После перепрошивки я не имею право взять и стереть, вообще-то проект писался несколькими людьми, я всего лишь свою работу делаю, сказали, значит так надо.  Никакой очистки не допускается, то есть после перепрошивки  МК должен автоматом распознать что там мусор и проинициализировать указатели, если там мусора нет, значит должен найти начало и конец и продолжить работу, то есть древние сообщения, которые были записаны до выключения питания, не удалять.

есть разметка в EEPROM

LOG_BUF_START 0x100
LOG_BUF_SIZE   256
LOG_BUF_END   LOG_BUF_START+LOG_BUF_SIZE

вот мой сектор, что хочу что и делаю с ним.. smile





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


Эксперт
****


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

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



Цитата(daemonaz @  28.10.2010,  18:28 Найти цитируемый пост)
вот здеся и будет геморой с блоками..
Будет не геморой, а полное переписывание всего с нуля. 
Цитата(daemonaz @  28.10.2010,  18:28 Найти цитируемый пост)
После перепрошивки я не имею право взять и стереть
Свою область стереть нельзя?  smile 
Цитата(daemonaz @  28.10.2010,  18:28 Найти цитируемый пост)
Никакой очистки не допускается, то есть после перепрошивки  МК должен автоматом распознать что там мусор и проинициализировать указатели,
Один раз это сделать можно, но потом, когда начнется запись лога, это уже не будет мусор. Так что надо либо явно прописывать метку конца и перезаписывать ее с каждой новой записью (что отрицательно скажется на ресурсе флэша), либо все же протереть свое место (один раз). Надеятся на то, что каких то многобайтовых последовательностей в старом образе прошивки не найдется нельзя - это не даст 100% гарантию, все может найтись  smile 


PM MAIL   Вверх
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   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

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


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

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

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


 




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


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

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