|
|
  |
Интересный глюк в CodeVisionAVR |
|
|
|
Dec 3 2008, 21:26
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата defunct[/b]' date='Dec 3 2008, 05:15' post='510351'] Неочевидно, потому что ваш пример вообще неоткомилируется, неизвестно что такое rus  (1) Очень странно как вы использовали этот код и не наткнулись на проблему раньше, ведь 3/4 символов, в т.ч. и цифры, были недоступными! (2) 1. Извините, это моя ошибка. Я описывал проблему выхода из функции и не подумал, что людей могут заинтересовать совсем другие вопросы. Вы правы, конечно этот код в таком виде не откомпилируется! Ладно, попробую ответить на ваш вопрос. Начну с проблемы LCD, поскольку, у человека, который их ни разу не использовал возникают непонятки. У всех символьных LCD имеется встроенный знакогенератор (ну как минимум мне еще не попадались симольные LCD без оного). Младшая половина знакогенератора соответствует кодам ASCII. Проблемы заложены в старшей половине. Если у вас НЕ руссифицированный LCD, то, собственно, проблемы нет, т.к. в знакогенераторе кирилицы -- нет. Если LCD руссифицированный, то возникает проблема кодировки. Дело в том, что эта кодировка не совпадает ни с 866, ни с 1251. Я так понимаю, что производитель экономил память -- там, где изображение кириллических символов совпадает с изображением латинских символов, кириллические символы выкидывались. Например, кириллическая буква Р и латинская P, О и О, Н и Н, ну и т.д. Т.е. половина кириллического алфавита оказалась расположена в латинском. Понятно, что кодировка получилась весьма веселая. С другой стороны, поскольку мы все пишем свои проги под Виндой, то стринги в исходниках тоже имеют виндовую кодировку. Теперь если прогу откомпилировать и залить в МК, то на LCD русские сообщения исказятся до неузнаваемости. Стало быть нужно произвести перекодировку. Это можно сделать либо до компиляции, либо во время исполнения проги в МК. Поскольку, объем флешь-памяти меня не напрягал, а вывод текстовой инфы на LCD занимает очень незначительное время, я решил незаморачиваться с перекодировкой до компиляции, а выполнять ее во время вывода строк. Тем более, что в проектах могут встретиться задачи, где стринг может прийти извне, например по RS232. Соответственно во флешь-памяти МК располагалась таблица перекодировок. Имя этой таблицы -- rus. Функция перекодировки называлась translate. Мне показалось, что это очевидные вещи, и я поэтому не стал особо заострять на этом внимание. Надеюсь, что я ответил на Ваш первый вопрос. 2. Вопрос будет посложнее. Если честно, то ахренегознаеттоваришмайор! Я могу только предполагать, что это особенность CV. Т.е. переменная data и результат функции раполагались в одном и том же регистре. Иначе говоря, если "насильственной" перекодировки не происходило, то функция возвращала то, что получала в качестве аргумента. Еще раз повторю -- то, что я описал, такой код должен быть приравнен к ошибке. Компилятор пропустил. В моем случае, это не имело ни каких последствий (кроме, разве что, моего запоздалого испуга). 2 Nick_Shl Я обычно поднимаю все флаги на ошибки и предупреждения.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Dec 3 2008, 23:53
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Сергей Борщ @ Dec 3 2008, 17:35)  Тогда вам в gcc. Такого шикарного инлайн-асма в других компиляторах не встречалось. Вставленный код не мешает оптимизатору, компилятор сам решает, в каких регистрах удобнее передать параметры в ваш ассемблерный кусок... Конфетка! Не знаю как CV, но ИАР встретив в функции инлайн-асм складывает крылья и выключает оптимизатор (где-то в описании было). А я не испытал серьёзных неудобств с асмовыми вставками в IARе. (Дальнейшее к Вам Сергей не относится, так как Вы всё это знаете лучше меня, это больше для delamoure и других, выбирающих инструмент) Начнём с того, что IAR позволяет использовать inline ассемблер. В том числе и с многострочными конструкциями. Во-вторых он позволяет писать на ассемблере законченные процедуры и подключать на этапе линковки. Это на мой взгляд намного правильнее и логичнее. Прога получается значительно нагляднее и завершённее. Использование регистров компилятором детально описано, и при таком варианте я не заметил ухудшения работы оптимизатора. (А inline ассемблер не применял, по причине вышеописанной) Во втором варианте возможно использовать общие символические имена. Причём я работал со структурами, массивами, флагами именно с символьными именами. Несколько напрягает в IARе перевод всех символьных имён в регистры и константы десятичные. И это перед выдачей листинга. Ну например исходный текст int i=1234; В распечатке асмового листинга мы увидим что-то типа ldi r26,210 ldi r27,4 Я бы предпочёл увидеть что-нибудь типа ldi R26,low(1234) ldi R27,high(1234) Аналогично и с именами символическими. Хотя наверное это брюзжание.
|
|
|
|
|
Dec 4 2008, 00:52
|

Частый гость
 
Группа: Свой
Сообщений: 176
Регистрация: 2-04-08
Из: Днепропетровск
Пользователь №: 36 406

|
Впрочем, IAR для меня не новость  "Многострочные конструкции inline ассемблера" вызывают оторопь: "where \n (new line) separates each new assembler instruction". И это удобно? На этапе линковки свой ассемблерный код не подключал. Коллега мне демонстрировал как это делается еще года 3 назад. Также способ описан в инете, по-моему, кем-то из местных (Сергеем Борщом?). Показалось неудобно, долго. Когда код писать? Тут целый обряд с бубном протанцевать необходимо.
--------------------
Ребята, как же это вы без гравицапы пепелац выкатываете из гаража? Это непорядок. ©
|
|
|
|
|
Dec 4 2008, 04:57
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(SasaVitebsk @ Dec 4 2008, 02:53)  Во-вторых он позволяет писать на ассемблере законченные процедуры и подключать на этапе линковки. Это на мой взгляд намного правильнее и логичнее. Это очень спорный момент. Ассемблерные вставки обычно делаются для повышения быстродействия. Использование написанных на ассемблере законченных процедур однозначно порушит стратегию оптимизатора и вместо выигрыша по времени можно получить проигрыш. Особенно если ассемблерная функция маленькая и быстрая. Тут может быть и большой оверхед - регистровые переменные в стек, рабочие копии обычных сохранить по "месту прописки". По выходу из ассемблерной функции все проделать в обратном порядке. А ведь бедный ИАР не знает, что в этой внешней процедуре происходит с регистрами, вот и сохранит по максимуму. У GCC видимо при такой методике включения S файлов должны быть похожие трудности. А вот инлайн ассемблер у GCC выше всяких похвал. Именно его использование и позволяет достичь максимального быстродействия - в этом случае накладных расходов или вообще нет, или они малы. А в отдельных файлах удобно обработчики прерываний делать.
|
|
|
|
|
Dec 4 2008, 08:20
|

Знающий
   
Группа: Свой
Сообщений: 966
Регистрация: 27-05-06
Из: СПб
Пользователь №: 17 499

|
Цитата(_Pasha @ Dec 3 2008, 17:22)  Интересно, какие грабельки еще подкинет 16-битная недо-арифметика  А вот я уже привык  ибо влом перелопачивать старые проекты под gcc... CV всегда под рукой... просто надо знать в каких случаях если справа у одного из операндов стоит младший тип и производится умножение/сложение/сдвиг что будет с результом ... например умножать char на int некорректно, а наоборот- можно  но вообще-то всегда варнинги генерятся их надо внимательно читать и все будет ок.
|
|
|
|
|
Dec 4 2008, 09:36
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(SasaVitebsk @ Dec 4 2008, 01:53)  А я не испытал серьёзных неудобств с асмовыми вставками в IARе. .... (А inline ассемблер не применял, по причине вышеописанной)  "Асмовые вставки" == inline assembler. Они, как правильно заметил Qwertty, хороши именно тем, что не надо тратить время на сохранение регистров и вызов функции. При этом gcc позволяет в такой вставке сделать все, что угодно, а ИАР в документации честно пишет: Цитата Inline assembler sequences have no well-defined interface with the surrounding code generated from your C or C++ code. This makes the inline assembler code fragile, and will possibly also become a maintenance problem if you upgrade the compiler in the future. ... Inline assembler is therefore often best avoided. If there is no suitable intrinsic function available, we recommend the use of modules written in assembler language instead of inline assembler, because the function call to an assembler routine normally causes less performance reduction.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 4 2008, 10:25
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(ARV @ Dec 4 2008, 14:51)  а как можно преобразовать строки для вывода на LCD на этапе компиляции? так, чтобы в исходном тексте они были в первозданном виде, а в объектном файле - уже перекодированные? понимаю, что надо как-то влезть в последовательность работы препроцессора, но как? Я не совсем точно выразился. Имел ввиду, что у программы (в общем смыле) имеются несколько этапов жизни (или как это правильно сказать?). Этап разработки, написания теста, компиляция -- это все есть первый этап. Второй этап -- это, собственно, работа бинарного модуля в изделии, ран-тайм. Первый этап я условно назвал -- "на этапе компиляции". Что, видимо, и внесло путаницу в понимание. На самом деле, вряд-ли кто осмелиться "отхачить" компилятор так чтобы тот "на этапе компиляции" (в буквальном смысле) конвертировал кодировку стрингов. Мою фразу "преобразовать строки для вывода на LCD на этапе компиляции" следует понимать так: на этапе написания исходных текстов вы должны стринги набирать как они есть -- в Виндовой кодировке. Вы ведь все равно будете компилировать прогу не один раз, пока не исправите все ошибки. И вам, скорее всего, понадобится видеть читаемые строки. А когда ошибки будут устранены (т.е. перед окончательной (последней) компиляцией, сборкой), вы должны или руками, или с помощью самопальной проги-конвертора, найти стринги и заменить в них символы на нужную кодировку. Когда стрингов не так много, это быстрее сделать руками по табличке-шпаргалке. Когда же проект достаточно большой и развесистый, то проще написать утилиту, которая будет выискивать в тексте скармливаемых ей файлов стринги и заменять в них байты. Кроме того, надо учитывать, что конвертации могут подвергаться не только стринги, а и одиночные символы. Т.е. проблема еще та! ЗЫ 1. Сергей Борщ немного раньше ответил. 2. Еще раз хочу напомнить, что стринги и символы могут приходить из внешнего мира. Т.е. задачу перекодировки удобнее решать на этапе ран-тайм, непосредственно в драйвере LCD. В этом случае вообще никаких проблем не будет. Единственная неудобство -- это незначительное снижение быстродействия при выводе и небольшое увеличение кода программы. Но поскольку, доля времени на перекодировку соизмерима или даже меньше, чем время на дергание лапок у LCD, а поток выводимой на LCD информации вообще никакой, то практически перекодировка в режиме ран-тайм не оказывает никакого торможения.
Сообщение отредактировал zhevak - Dec 4 2008, 10:37
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Dec 4 2008, 10:26
|
Частый гость
 
Группа: Участник
Сообщений: 127
Регистрация: 18-10-06
Пользователь №: 21 418

|
Цитата(zhevak @ Dec 4 2008, 01:26)  Если LCD руссифицированный, то возникает проблема кодировки. Дело в том, что эта кодировка не совпадает ни с 866, ни с 1251. Я так понимаю, что производитель экономил память -- там, где изображение кириллических символов совпадает с изображением латинских символов, кириллические символы выкидывались. Например, кириллическая буква Р и латинская P, О и О, Н и Н, ну и т.д. Т.е. половина кириллического алфавита оказалась расположена в латинском. Понятно, что кодировка получилась весьма веселая. Существуют индикаторы с 1251 кодировкой (как одной из возможных). Делает фирма МЭЛТ.
|
|
|
|
|
Dec 4 2008, 10:47
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(LordVader @ Dec 4 2008, 15:26)  Существуют индикаторы с 1251 кодировкой (как одной из возможных). Делает фирма МЭЛТ.
да. Спасибо. Я вам больше скажу -- в мире существуют LCD с SPI интерфейсом... правда я их как-то не видел в продаже. Давайте сойдемся на том, что все это из разряда экзотики. В магазинах в основном продают LCD с "компактной" кодировкой и с традиционным интерфейсом.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|