Форум проекта "Минилаб-Мастер"

Клуб по интересам - отдыхаем от фотобизнеса => Art Of Electronics => Тема начата: Andy от 10 Декабря 2009, 16:36:04

Название: Малтиязычность в AVR
Отправлено: Andy от 10 Декабря 2009, 16:36:04
Тут такая проблема есть - в коде моего дивайса есть куча сообщений, выводящихся на дисплей LSD. Они щаз заведены в сроковые константы под именами и выводятся по мере необходимости на экран. Проблема в том, что используются в данный момент два стандарта русскояозычных кодировк вывода на LSD дисплей. Хочется все сообщения хранить в епиромке чипа и загружать туда при самопрограммировании. Сама загрузка - не проблема, проблема в том, разработать алгоритм, который вытягивал из епиромки нужные сообщения и печатал их. Сами сообщения будут одной длины во всех кодировках. То есть чел, имея определеный дисплей прошивает епиром контроллера нужной кодировкой. Допустимо, что одна из кодировок по умолчанию уже есть в коде программы, но ее можно заменить другой, считанной из епиром чипа.

Вот, рву себе мозг..
Название: Re: Малтиязычность в AVR
Отправлено: Andy от 10 Декабря 2009, 16:43:51
Например один чип дисплея правильно отобразит фразу

"Превед медвед! "

А другому чипу эту фразу надо послать как

"Ёpeіeг јeгіeг! " 

Тогда он отобразит ее именно как "Превед медвед! "


Хоца, чтобы прога поддерживала обе кодировки, но сообщения в коде дублировать неооооохота... Ибо чип не резиновый, задумок вагон, и загрузчик 4 кило отжирает опять же....
Название: Re: Малтиязычность в AVR
Отправлено: jumper_at_home от 10 Декабря 2009, 16:47:42
   Нужна табличка указателей на список. Пойнтеры в Сишной терминологии. Чтобы не городить алгоритмы обработи завести вторую табличку с длинами текстовых строк. По первой табличке получаем смещение текстовой строки от начала буфера, по второй длину. Быстро и четко.
 

    
Название: Re: Малтиязычность в AVR
Отправлено: Andy от 10 Декабря 2009, 17:12:47
Звучит заумненько ...
Название: Re: Малтиязычность в AVR
Отправлено: Andy от 10 Декабря 2009, 17:14:00
И главное чтобы алгоритм не разросся до длины сэкономленных строк...  :)
Название: Re: Малтиязычность в AVR
Отправлено: jumper_at_home от 11 Декабря 2009, 07:39:59
  Ну смотри (сегмент данных):

   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 и т.д.)

Название: Re: Малтиязычность в AVR
Отправлено: pumpkin от 11 Декабря 2009, 12:21:55
@ Andy Ты хочешь чтоб сообщения хранились отдельно от кода? Т.е., когда ты выпускаешь обновление прошивки, она идет в виде отдельно кода и отдельно двух ресурсных файлов с строками разных кодировок, и хозяин железки шьет код и свой ресурс в разные участки еепрома. А программа во время работы динамически извлекает строки из ресурсного участка памяти?

Или другое - ты компилируешь из одного исходника две версии прошивки, с уже встроенными строками разных кодировок?
Название: Re: Малтиязычность в AVR
Отправлено: Andy от 11 Декабря 2009, 14:36:38
В очередной раз снимаю шляпу перед настоящими программерами...
Они умеют задавать безупречные вопросы.

Логика рулит, вот мне бы так..

Первый вариант. По умолчанию залита одна кодовая страница. Вернее сообщениями с нужной кодировкой. Но ее всегда можно поменять прошивкой. Боот будет прошивки различать и знать что залить - бут самого контроллера или в епиром что закинуть. Но в идеале да - обе кодировки в епиром, а в контроллере сделать выбор одной из них. В меню контроллера ключевые фразы будут на английском. Я еще не считал размеры сообщений, но думаю 1 килобайта епиромки должно хватить.
Название: Re: Малтиязычность в AVR
Отправлено: Andy от 11 Декабря 2009, 14:45:47
Вот как у меня выглядит щаз:

Цитировать
\' ------------------------- Слова ---------------------------------------------


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ї"                                          \'Тест


Хотелось бы вынести эту фигню в епиром в нескольких вариантах и выбирать по адресу.

Название: Re: Малтиязычность в AVR
Отправлено: jumper_at_home от 11 Декабря 2009, 14:45:59
  Кодировки разные или языки разные? Или и то и другое?
Название: Re: Малтиязычность в AVR
Отправлено: Andy от 11 Декабря 2009, 14:52:35
Допустим, кодировки. То есть длина сообщений будет всегда одинакова.
Название: Re: Малтиязычность в AVR
Отправлено: Andy от 11 Декабря 2009, 15:10:32
Если важно - дисплей однострочный, 16-ти символьный, но логически разделен на два блока по 8 символов. Длинные сообщения склеивает и выводит на дисплей специальная подпрограмма. Имеются функции полного перехода между блоками и управленя знакоместом и прочая прочая....
Название: Re: Малтиязычность в AVR
Отправлено: pumpkin от 11 Декабря 2009, 17:21:27
@ Andy

Тебе надо будет для начала придумать формат хранения ресурсов и сделать нечто вроде компилятора этих ресурсов. Например:


Offset | Size     | Comment
----------------------------------
0      | 4 байта  | Версия
4      | 1 байт   | Кодировка
5      | 2 байта  | Количество строк (N)
7      | N*2 байт | Индекс (см. код jumper_at_home )
7+N*2  | X байт   | Строки друг за другом без разделителя


Но я думаю компилить 2 прошивки с одного исходника с уже вложенными строками будет экономнее с точки зрения занимаемого места. Каждая прошивка имеет один код, но разные строки.
Название: Re: Малтиязычность в AVR
Отправлено: Andy от 11 Декабря 2009, 17:51:07
 :o Гениально, я как то об этом и не думал...
Название: Re: Малтиязычность в AVR
Отправлено: pumpkin от 11 Декабря 2009, 18:19:45
Я бы сделал так (и проще и экономнее):
Вынес все 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 языковые версии прошивки из одного исходника.
Название: Re: Малтиязычность в AVR
Отправлено: pumpkin от 11 Декабря 2009, 18:34:42
Или сразу так:
Цитировать
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.
Название: Re: Малтиязычность в AVR
Отправлено: Andy от 18 Мая 2011, 15:23:10
Давно решил проблему, найдя в сети сишный код перевода русской кодировки в код, понятный жк индикаотору и переделав его под 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