Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Почему не работает код?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
DMD
Не могу понять - почему не работает код, когда тут вроде бы висеть нечему! Компилятор - CodeVision, славится своей тупизной в общении с типами данных. Контроллер - ATMega8535.
Почему-то вот такой код не работает:
Код
//....
typedef unsigned char byte;
typedef unsigned long int dword;

dword SID = 0L;

typedef struct
{
    byte extended_identifier;
    dword identifier;      //32 bit
    // data length:
    byte  dlc;
    byte  dta[8];
    // Acceptence Filter that enabled the reception
    byte  filhit;
    byte rtr;
} CanMessage;

...
//теперь необходимо сдвинуть идентификатор на 5 бит влево...
SID = (dword)(((dword)(msg.identifier)) << 5);      

//Вот тут и висим, непонятно почему...
//так как следующий оператор ничего в порт не выводит:

printf("Packet observed: SID=0x%04lX; data: ", SID);
for (i=0; i<=7; i++) printf("[0x%02X] ", msg.dta[i]);
printf("\n");      
LED_WORK = 0;
//...

Вот почему висим там? Чему там висеть-то??
Qwertty
Цитата(DMD @ May 16 2008, 21:48) *
Вот почему висим там? Чему там висеть-то??

ЕМНИП у CV имеется настройка возможностей printf - в опциях компилятора. По умолчанию кажется стоит такая, что тип long не воспринимается.
DMD
Нее, тут все ОК, я тоже думал. Стоит long,width опция
plombir
Код
typedef unsigned long int dword;

вот это я не понял, что за запись....
dword - какая размерность?
DMD
32 бита
defunct
Цитата(DMD @ May 16 2008, 22:45) *
32 бита

не хотите попробовать нормальный компилятор?
не придется городить в коде черт знает что smile.gif

это же ужОс:
Цитата
SID = (dword)(((dword)(msg.identifier)) << 5);


SID - dword,
identifier тоже dword

для нормального компилятора достаточно просто написать
SID = msg.identifier << 5;

да и тип звучал бы так:
typedef unsigned long dword;


Цитата
Почему-то вот такой код не работает

Может проблемы со стеком? Все же в 8535 памяти не так много, а у вас там "нидецкие" printf'ы
DMD
"нидецкие" printf - это чисто для отладки. Нормальный компилятор давно ищу и не могу найти, не подскажете?
SID = msg.identifier << 5; - так не пробовал, но боюсь, что на какой-нибудь косяк компилятора нарвусь... "Косяк" - потому что кто-то посчитал, что преобразование к int перед, к примеру, сдвигом - операция ненужная в целях экономии чертовой памяти... Поэтому вот такой код не работает (хоть и компилится на все 100%):

unsigned char t = 255;
unsigned f = t << 3;

И такая штука твориться только в CodeVision, я на ней неделю просидел - все не мог вдуплить чего там твориться... Пришлось копаться в ассемблере. ..
defunct
Цитата(DMD @ May 17 2008, 01:46) *
"нидецкие" printf - это чисто для отладки.

Да понятно что для отладки, но память то они все равно жрут ;>

Цитата
Нормальный компилятор давно ищу и не могу найти, не подскажете?

Компиляторы (нормальные) -

Бесплатный WinAVR (avrgcc) встраивается в AVR-Studio (только самый последний релиз не советую брать он еще сырой, стабильная версия "на сейчас" 20071221).

Небесплатный IAR-Systems с IDE IAR-EWAVR, the best for AVR.

С ними хоть можно не так сильно бояться насчет
Цитата
что на какой-нибудь косяк компилятора нарвусь...
Nick_Shl
Цитата(DMD @ May 17 2008, 01:46) *
unsigned char t = 255;
unsigned f = t << 3;
Хелп читать надо и по настройкам лазить! Советские инженеры блин...
Все правильно компилятор делает! Контроллер-то 8-ми битный! операции над int'ами занимают больше времени чем над char'ами. Хотите пример? Пожалуйста:
Код
;   char a,b,c;
;   a -> R17
;   b -> R16
;   c -> R19

;   a = b + c;
    MOV  R30,R19
    ADD  R30,R16
    MOV  R17,R30

;   a = (char)((int)a + (int)b);
    MOV  R26,R17
    LDI  R27,0
    SBRC R26,7
    SER  R27
    MOV  R30,R16
    LDI  R31,0
    SBRC R30,7
    SER  R31
    ADD  R30,R26
    MOV  R17,R30
Какой код будет работать быстрее? Может такты посчитаем?
Но если вам все равно на скорость, а хочется "правильности" то вам сюда:
Project -> Configure -> C compiler -> Code generation -> Promote char to int
WHALE
да,все правильно,только имхо галочку они неправильно назвали-надо было назвать типа стандартный С
Но я в таких ситуациях обычно прагмой #pragma promotechar+ разруливаю,если нужна скорость,конечно.Если нет,то птица в конфигурации проекта.
Сергей Борщ
Цитата(DMD @ May 17 2008, 01:46) *
так не пробовал, но боюсь, что на какой-нибудь косяк компилятора нарвусь...
integer promotion rules распространяются на типы меньше int размером. В противном случае левая и правая части подвыражения приводятся к наибольшему типу, который у вас совпадает с типом результата. Так что тут приведение совершенно лишнее.
Цитата(Nick_Shl @ May 17 2008, 07:42) *
Советские инженеры блин...
Все правильно компилятор делает!
Как "правильно" - написано в стандарте. Нормальный компилятор для обоих ваших примеров должен был бы сгенерить одинаковый код. Теперь сравните код для такого примера:
Код
unsigned char a = 200;
unsigned char b = 200;

volatile unsigned int c = a + b;
volatile unsigned int d = (unsigned int)a + (unsigned int b);
По стандарту результаты должны быть идентичны. Также внимательно прочитайте пост №7 - там тоже очень красивый пример.
Цитата(Nick_Shl @ May 17 2008, 07:42) *
Контроллер-то 8-ми битный! операции над int'ами занимают больше времени чем над char'ами.
То есть вы считаете, что быстрый неправильный код лучше медленного, но правильного? Тогда каким инженером назвать вас? Индийским? Китайским?
WHALE
Насколько я знаю,многие компиляторы допускают возможность отступления(расширения) стандарта.
В билдере есть,в иаре тоже есть галка типа "использовать стандартный с/c++.В CV тоже самое,есть возможность выбора.Хочешь по стандарту-поставь один раз галку при конфигурировании проекта и все.
И вообще вышла новая версия CV-полный редизайн.Обьем инсталяхи увеличился почти в 4 раза!Первая фраза в описании-new ANSI C compatible C front-end.Судя по описанию-С99.
Nick_Shl
Цитата(Сергей Борщ @ May 17 2008, 13:08) *
То есть вы считаете, что быстрый неправильный код лучше медленного, но правильного? Тогда каким инженером назвать вас? Индийским? Китайским?
А что значит не правильный? Если надо - используйте явное и логичное приведение типов - и все будет ок. Если компилятор работает не так как вы ожидаете, это не значит, что он "не правильный"! Кто вам вообще сказал, что этот компилятор полностью соответствует Си? Опять открываем хелп и читаем:
Цитата
The C cross-compiler implements nearly all the elements of the ANSI C language, as allowed by the AVR architecture, with some features added to take advantage of specificity of the AVR architecture and the embedded system needs.
То есть "близко к Си, адаптировано под AVR". И это правильно. А то потом будут говорить: "все компиляторы гавно, в полной мере можно только на асме ядро использовать".
Я стандартов не читал, хотя на Си уже достаточно давно работаю. А про это правило только недавно из этого форума узнал. И честно говоря мне оно не нравится, как и любая другая не явная вещь...
И вообще, Си(под x86) мне понравился тем, что позволяет сделать то же, что и на асме(и я тогда пожалел, что классе в 9-ом учил асм, а не Си), а если он не будет позволять, зачем он тогда нужен?
WHALE
Цитата(Nick_Shl @ May 17 2008, 18:30) *
Я стандартов не читал, хотя на Си уже достаточно давно работаю. А про это правило только недавно из этого форума узнал. И честно говоря мне оно не нравится, как и любая другая не явная вещь...

а си познавали через астрал,напрямую подсоединившись к ноосфере? smile.gif
а если как все по книжкам,то в любой книге по С правила приведения типов расписаны очень подробно.да их и не много,на полстранички вмещаются.
З.Ы. а с приоритетом операций у вас та-же фигня?
Nick_Shl
Цитата(WHALE @ May 17 2008, 19:16) *
а си познавали через астрал,напрямую подсоединившись к ноосфере? smile.gif
Почти. В основном в универе(у нас был хороший преподаватель). Учебники не люблю. А вот книжка "Полный справочник по С" Шилдта то что надо + MSDN. Но в справочники лезут или когда чего-то не знают или когда что-то не работает. Поэтому про то самое "Promote char to int" и не знал - это знание мне было просто не нужно.
Вообще после асма Си очень легко дался. Кстати у нас сначала преподавали Си, а потом асм, что считаю не правильно - мало кто понял с первого раза что такое указатели...

Цитата(WHALE @ May 17 2008, 19:16) *
З.Ы. а с приоритетом операций у вас та-же фигня?
Да вроде нет. Если не уверен - то можно и скобочки поставить. smile.gif
А вобще если возникают такие проблемы, то лучше пользоваться обратной польской записью. smile.gif
WHALE
а я по книжкам.Кстати-у нас с вами одна библия. smile.gif отличный справочник.
DMD
Спасибо, ребята, за помощь. В понедельник на оборудовании посмотрю, сообщу вам.
Спасибо!
DMD
Ребят, а последней версии CodeVision у вас нет с лекарством?
WHALE
Цитата(DMD @ May 18 2008, 11:28) *
Ребят, а последней версии CodeVision у вас нет с лекарством?

Увы,нет,ждемс... crying.gif Очень интересно глянуть,что там наворотили...
З.Ы. а вообще права поговорка-"старый глюк лучше новых двух". за 2 недели уже 2 версии с кучей багфиксов вышли.Но наверно,это нормально.
Nick_Shl
Цитата(DMD @ May 18 2008, 10:28) *
Ребят, а последней версии CodeVision у вас нет с лекарством?
Последней нету... Видать недавно вышла. У меня 1.25.8 Pro
Кстати там предупреждение висит:
Цитата
WARNING. Using the commercial versions of CodeVisionAVR with pirated license files, created with Keygens, will result in incorrectly generated code, even if CodeVisionAVR seems to accept the pirated license file. The entire responsibility for any problems or losses arising from the usage of a pirated license file lies entirely on the person who tried to illegally use our program. We do not provide technical support for users of pirated license files.
Так что на вид может быть и сломано, а код будет левый...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.