Форум проекта "Минилаб-Мастер"
Клуб по интересам - отдыхаем от фотобизнеса => Art Of Electronics => Тема начата: Andy от 10 Декабря 2009, 16:36:04
-
Тут такая проблема есть - в коде моего дивайса есть куча сообщений, выводящихся на дисплей LSD. Они щаз заведены в сроковые константы под именами и выводятся по мере необходимости на экран. Проблема в том, что используются в данный момент два стандарта русскояозычных кодировк вывода на LSD дисплей. Хочется все сообщения хранить в епиромке чипа и загружать туда при самопрограммировании. Сама загрузка - не проблема, проблема в том, разработать алгоритм, который вытягивал из епиромки нужные сообщения и печатал их. Сами сообщения будут одной длины во всех кодировках. То есть чел, имея определеный дисплей прошивает епиром контроллера нужной кодировкой. Допустимо, что одна из кодировок по умолчанию уже есть в коде программы, но ее можно заменить другой, считанной из епиром чипа.
Вот, рву себе мозг..
-
Например один чип дисплея правильно отобразит фразу
"Превед медвед! "
А другому чипу эту фразу надо послать как
"Ёpeіeг јeгіeг! "
Тогда он отобразит ее именно как "Превед медвед! "
Хоца, чтобы прога поддерживала обе кодировки, но сообщения в коде дублировать неооооохота... Ибо чип не резиновый, задумок вагон, и загрузчик 4 кило отжирает опять же....
-
Нужна табличка указателей на список. Пойнтеры в Сишной терминологии. Чтобы не городить алгоритмы обработи завести вторую табличку с длинами текстовых строк. По первой табличке получаем смещение текстовой строки от начала буфера, по второй длину. Быстро и четко.
-
Звучит заумненько ...
-
И главное чтобы алгоритм не разросся до длины сэкономленных строк... :)
-
Ну смотри (сегмент данных):
str[1]="Это первое сообщение";
str[2]="Это второе";
str[3]="Это черт пойми какое";
void *ptr[]= 0, 20, 29; <-массив смещений от начала.
int length[] = 20, 9, 19; <-массив длин строк (не обязателен)
char* tempstr;
int strindex; <- переменная под индекс сообщения
tempstr = new char[1024]; <- выделение памяти под строку (длина - килобайт)
memcpy(tempstr, ptr[strindex], length[strindex]); <- копируем в tempstr нужную строку.
printf(tempstr);
...
в конце delete tempstr; <- освобождаем память.
Загружая кусок памяти с сообщениями + массив ссылок (и длин) получаешь то, что надо. Как работать с этим - придумаешь. Длины можно вычислять и без массива - численная разница текущего и следующего указателя. Заодно не надо стремиться к тому, чтобы сообщения на разных языках имели одинаковую длину.
Так организованы строки в С и С++. Не удивлюсь что и в других языках тоже (кроме С и Асма с другими мало знаком).
В С строка оканчивается символом 0x00. Можно сделать так же, тогда не надо длину вычислять. Почитай в инете. Функции strХХХ (strcpy, strlen, strcat и т.д.)
-
@ Andy Ты хочешь чтоб сообщения хранились отдельно от кода? Т.е., когда ты выпускаешь обновление прошивки, она идет в виде отдельно кода и отдельно двух ресурсных файлов с строками разных кодировок, и хозяин железки шьет код и свой ресурс в разные участки еепрома. А программа во время работы динамически извлекает строки из ресурсного участка памяти?
Или другое - ты компилируешь из одного исходника две версии прошивки, с уже встроенными строками разных кодировок?
-
В очередной раз снимаю шляпу перед настоящими программерами...
Они умеют задавать безупречные вопросы.
Логика рулит, вот мне бы так..
Первый вариант. По умолчанию залита одна кодовая страница. Вернее сообщениями с нужной кодировкой. Но ее всегда можно поменять прошивкой. Боот будет прошивки различать и знать что залить - бут самого контроллера или в епиром что закинуть. Но в идеале да - обе кодировки в епиром, а в контроллере сделать выбор одной из них. В меню контроллера ключевые фразы будут на английском. Я еще не считал размеры сообщений, но думаю 1 килобайта епиромки должно хватить.
-
Вот как у меня выглядит щаз:
\' ------------------------- Слова ---------------------------------------------
Const W1 = "аёіa№c v0.8beta" \'Дивайс v0.8 beta
Const W2 = "Pa·paІoїєa Andy" \'Разработано Andy
Const W3 = "KaccГ - " \'Касс -
Const W4 = "MecЗе ЅaАa»a:" \'Месяц начала:
Const W5 = "CјeЅa" \'Смена
Const W6 = "ҐЅёеёa»ё·aеёЗ..." \'Инициализация
Const W7 = "OїАeї " \'Отчет:
Const W8 = "HaАa»o:" \'Начало:
Const W9 = "KoЅeе:" \'Конец :
Const W10 = "Ў»aіЅoe јeЅЖ"
\'Главное меню
Const W11 = "OїАeїГ- " \'Отчеты-
Const W12 = "CoxpaЅЗeј..." \'Сохраняем...
Const W13 = "¤aґpy·єa І»oєa" \'Загрузка блока
Const W14 = "¤aґpy·єa EPROM" \'Загрузка EPROM
Const W15 = "BГґpy·єa EPROM" \'Выгрузка EPROM
Const W16 = "C дёcє. ѕo гaїaј" \'С фиск. по датам
Const W17 = "C дёcє.ѕo cјeЅaј" \'С фиск. по сменам
Const W18 = "Ўoг.Kіapї.MecЗе" \'Год.Кварт.Месяц
Const W19 = "Ёo јecЗеaј" \'По месяцам
Const W20 = "Ёo єіapїa»aј" \'По кварталам
Const W21 = "Ёo ґoгaј" \'По годам
Const W22 = "CєopocїД COM1200" \'Скорость COM1200
Const W23 = "Oїѕpaі»З№їe дa№»" \'Отправляйте файл
Const W24 = "¤aґpy·єa - Oє!" \'Загрузка - OK!
Const W25 = "BГґpy¶aeј EPROM" \'Выгружаем EPROM
Const W26 = "EPROM іГґpy¶eЅa" \'EPROM выгружена
Const W27 = "BГІop KaccГ" \'Выбор Кассы
Const W28 = "PaІoїa c єacco№" \'Работа с кассой
Const W29 = "Enter,ЁpoІe»-" \'Enter, Пробел-
Const W30 = "Ёap. HҐ" \'Пар. НИ
Const W31 = "Ёap. PEЈ" \'Пар. РЕЖ
Const W32 = "C " \'"C "
Const W33 = "Ёo " \'"По "
Const W34 = "Tecї" \'Тест
Хотелось бы вынести эту фигню в епиром в нескольких вариантах и выбирать по адресу.
-
Кодировки разные или языки разные? Или и то и другое?
-
Допустим, кодировки. То есть длина сообщений будет всегда одинакова.
-
Если важно - дисплей однострочный, 16-ти символьный, но логически разделен на два блока по 8 символов. Длинные сообщения склеивает и выводит на дисплей специальная подпрограмма. Имеются функции полного перехода между блоками и управленя знакоместом и прочая прочая....
-
@ Andy
Тебе надо будет для начала придумать формат хранения ресурсов и сделать нечто вроде компилятора этих ресурсов. Например:
Offset | Size | Comment
----------------------------------
0 | 4 байта | Версия
4 | 1 байт | Кодировка
5 | 2 байта | Количество строк (N)
7 | N*2 байт | Индекс (см. код jumper_at_home )
7+N*2 | X байт | Строки друг за другом без разделителя
Но я думаю компилить 2 прошивки с одного исходника с уже вложенными строками будет экономнее с точки зрения занимаемого места. Каждая прошивка имеет один код, но разные строки.
-
:o Гениально, я как то об этом и не думал...
-
Я бы сделал так (и проще и экономнее):
Вынес все Const wXX = "bla-bla-bla" строки в отдельные два файла, для каждой кодировки, например, strings1.bas и strings2.bas. А в коде использовал бы $include и/или #IF-#ELSE-#ENDIF :
Const Codepage = 1
#if Codepage = 1
$include "strings1.bas"
#else
$include "strings2.bas"
#endif
и изменяя только значение Codepage, компилироват 2 языковые версии прошивки из одного исходника.
-
Или сразу так:
Const Codepage = 1
#if Codepage = 1
Const w1 = "Строка 1"
Const w2 = "Строка 2"
Const w3 = "Строка 3"
#else
Const w1 = "String 1"
Const w2 = "String 2"
Const w3 = "String 3"
#endif
или с другой строны подойти. Например, главный модуль с кодом называется main.bas, делаем два файла firmware_cp1.bas:
$include "strings1.bas"
$include "main.bas"
и и firmware_cp2.bas:
$include "strings2.bas"
$include "main.bas"
компилируя их получим firmware_cp1.bin и firmware_cp2.bin.
-
Давно решил проблему, найдя в сети сишный код перевода русской кодировки в код, понятный жк индикаотору и переделав его под Bascom.
Вот функция печати. Немного громоздкая, так как переводит входящюю строку 16 символов (longstr) в жк кодировку и разбивает на 2 части для печати на однострочном индикаторе, с внутренней организацией 2x8 символов.
Printlsd:
For Otchet = 1 To 16
Ru = Mid(longstr , Otchet , 1)
Dig = Ru
If Dig > 191 Then
Dig = Dig - 192
Dig = Lookup(dig , Rusdata)
Mid(longstr , Otchet , 1) = Dig
End If
Next
Str1 = Mid(longstr , 1 , 8)
Str2 = Mid(longstr , 9 , 8)
Cls
Lcd Str1
Lowerline
Lcd Str2
Return
Rusdata:
Data &H41 , &HA0 , &H42 , &HA1 , &HE0 , &H45 , &HA3 , &HA4 , _
&Ha5 , &HA6 , &H4B , &HA7 , &H4D , &H48 , &H4F , &HA8 , _
&H50 , &H43 , &H54 , &HA9 , &HAA , &H58 , &HE1 , &HAB , _
&Hac , &HE2 , &HAD , &HAE , &HAD , &HAF , &HB0 , &HB1 , _
&H61 , &HB2 , &HB3 , &HB4 , &HE3 , &H65 , &HB6 , &HB7 , _
&Hb8 , &HB9 , &HBA , &HBB , &HBC , &HBD , &H6F , &HBE , _
&H70 , &H63 , &HBF , &H79 , &HE4 , &H78 , &HE5 , &HC0 , _
&Hc1 , &HE6 , &HC2 , &HC3 , &HC4 , &HC5 , &HC6 , &HC7