Оно выводится в окно "Build". А настройки Tools->Options->Messages->Show Build стоит в All или Messages ?
везде полазил, а в Options самой среды разработки не залез))) получилось. ОГРОМНОЕ СПАСИБО, Asteroid7!!!! стояло значение "warnings", поставил "messages" - теперь сообщение выводится. Если не затруднит, уточните, можно ли в этом сообщении выводить какие либо константы, объявленные заранее директивой #define?
Хочу выразить благодарность avreal и ARV. Заставили меня пересмотреть отношение к реализации критических секций на микроконтроллерах. Вопрос - "Почему зная об этом ты это не использовал?" - вогнал меня в небольшой ступор ) Мдаа, много думал...
Для GCC avreal класс критических секций привёл выше, а я приведу для IAR-a не подключая никаких хиадеров. Возможно, кому пригодится:
А вот пример, где логическая ошибка может быть для _любой_ архитектуры (хоть 128-битной), а предупреждения нет.
Код:
volatile char a; volatile char b; bool foo() { char ta = a; return ta == b; }
Не увидел в этом коде ошибки... Не затруднит Вас разъяснить этот момент. Единственное, что бросается в глаза, это логическое "==" без скобок. Так это допускается стандартом.
Если не затруднит, уточните, можно ли в этом сообщении выводить какие либо константы, объявленные заранее директивой #define?
Только текст, заключённый в скобки, выводится. В PDF файле help->AVR C/C++ Compiler Reference Guide можно это уточнить.
Мне не удалось найти применению этой #pragma message диррективы. Есть интереснее: #error. Она компиляцию останавливает. Удобно предкомпиляционные вычисления и наличие define-ов проверять. Например:
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
Только текст, заключённый в скобки, выводится. В PDF файле help->AVR C/C++ Compiler Reference Guide можно это уточнить.
Спасибо, Asteroid7, за ответ. Видимо остальным было влом отвечать. Я уже всю документацию перелопатил и очень много гуглил и яндексил:) действительно, я тоже не нашел как вывести константу, определенную директивой #define. Чтобы проверить какую то промежуточную константу приходится на этапе отладки добавлять в код строчки типа
Код:
#define A ((C+D)/B-D) ... TCCR0=A;
а потом просматривать ассемблерный листинг в этом месте. Очень неудобно. Насчет #error и #warning я тоже уже знаю) в принципе и до этого знал)))) Только там тоже нельзя выводить объявленные константы. кстати #warning не останавливает компиляцию (логично, скажете Вы ). А как Вы проверяете константы, расчет которых возлагаете на препроцессор?
P.S. может кому пригодится расчет значения регистра UBRR с округлением к ближайшему значению (для 16ти семплового приема):
Код:
enum{CPU_F_MHz=16}; enum{BAUD_RATE=115200}; // скорость обмена enum{CUR_UBRR_10x=(CPU_F_MHz*10000000/16/BAUD_RATE-10)}; //константа для записи в регистр UBRR умноженная на 10 enum{A=((CUR_UBRR_10x-5)/10),B=(CUR_UBRR_10x/10),C=B-A}; //(НАЧАЛО)округление константы для записи в регистр UBRR #if C==0x00 #define CUR_UBRR (A+1) #else #define CUR_UBRR B #endif //(КОНЕЦ) округление константы для записи в регистр UABRR ... // значение UBRR находится в CUR_UBRR UBRR=CUR_UBRR;
В аттаче добавил расчет UBRR в Excel.
Вложения:
Комментарий к файлу: Расчет UBRR в Excel Расчет UBRR.xls [25 KiB]
Скачиваний: 233
Для GCC avreal класс критических секций привёл выше, а я приведу для IAR-a не подключая никаких хиадеров.
Собственно, я привёл класс критической секции из AVR/GCC порта операционной системы scmRTOS, написанной на С++. Ваш пример можно сделать "несколько С++-нее", сделав сохранение состояния прерываний не присваиванием, а инициализацией.
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Не увидел в этом коде ошибки... Не затруднит Вас разъяснить этот момент. Единственное, что бросается в глаза, это логическое "==" без скобок. Так это допускается стандартом.
А её и компилятор не видит Я ж говорю, он не догадывается ни о чём. Тут может быть логическая ошибка, в точности та же, что и в Вашем примере про 8-битный контроллер и 16-битные данные. Если переменные a и b меняются в прерывании вместе и должны обрабатываться согласованно (я привёл сравнение просто в качестве примера примитивной обработки), то их надо читать обязательно в общей критической секции в две временные переменные и только потом обрабатывать. Но компилятор об этом не знает, поэтому и не предупреждает. В отличие от прямого сравнения a == b, где он ворчит о возможной зависимости от порядка чтения.
Кстати, не всегда даже 16-битную переменную (имеются ввиду 8-битники, конечно), изменяемую в прерывании, обязательно читать в крит. секции. Пусть у нас есть таймаут, декрементируемый в прерывании до 0.
Тут немного условно показано. И ISR без привязки к компилятору, и не показано само чтение. Можно timeout сделать объединением { uint16_t u; uint8_t b[2]; } и в макросах читать из байтовой части, можно в макросах обращаться по приведённому к (volatile uint8_t *) указателю со смещениями, не важно. Важно то, что прерывание только декрементирует переменную и 0 уже не трогает. С (и С++ для встроенного оператора &&) гарантирует, что вычисление операндов идёт слева направо с прекращением вычислений, когда результат уже ясен. Поэтому чтение сначала старшей части безопасно. Старшая часть если уже стала 0, то при анализе младшей уже не поменяется. А если ещё не 0, то младшая и не зачитывается. Если за время сравнения с 0 старшей части младшая меняется — ну и ладно. Если к тому времени сама станет нулём — тем лучше, раньше узнаем об окончании таймаута
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
А как Вы проверяете константы, расчет которых возлагаете на препроцессор? P.S. может кому пригодится расчет значения регистра UBRR с округлением к ближайшему значению (для 16ти семплового приема):
Я не смотрю глазами на сами константы. Если мне нужно проверить отклонение, то тогда из CURR_UBRR назад рассчитывается REAL_BAUD, потом
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Сперва в программе измеряется тактовая частота внутреннего RC-генератора (в попугаях, дабы уложиться в двухбайтовую переменную), потом вычисляется нужное значение регистра c округлением.
На этом форуме единицы, кто использует IAR. Но, последние полгода интерес к нему увеличился )
ibiza11 писал(а):
А как Вы проверяете константы, расчет которых возлагаете на препроцессор?
Например, проверка переполнения регистра OCR (8 бит) в качестве генерации меандра для разной частоты. Приведу утрированно, но смысл думаю будет понятен.
Код:
#define VAL_OCR( del, freq_hz ) ( ( QUARZ_FREQUENCY / ( del * freq_hz ) >> 1 ) - 1 )
//меандр для 1000 Hz #define VAL_OCR_1000 VAL_OCR( 128ul, 1000ul ) //меандр для 2000 Hz #define VAL_OCR_2000 VAL_OCR( 1ul, 2000ul )
#if VAL_OCR_1000 > 255 #error "1000 Hz - не влазит в байт. Нужно увеличить делитель" #endif
#if VAL_OCR_2000 > 255 #error "2000 Hz - не влазит в байт. Нужно увеличить делитель" #endif
Ваш пример можно сделать "несколько С++-нее", сделав сохранение состояния прерываний не присваиванием, а инициализацией.
Согласен, Ваш вариант красивее. Не то чтобы не доверяю, но навсякий случай перепроверил генерируемый код. Один в один.
avreal писал(а):
А её и компилятор не видит Я ж говорю, он не догадывается ни о чём.Тут может быть логическая ошибка, в точности та же, что и в Вашем примере про 8-битный контроллер и 16-битные данные.Если переменные a и b меняются в прерывании вместе...
Так я и думал - затупил. Не проанализировал при обоюдном изменении. )
Знаю что элементарно, и даже как то делал раньше, но забыл как. Мне нужно 4 младших бита переменной типа unsigned int занести в 11,12,13,14 бит другой переменной типа unsigned long int (естественно не меняя остальных). Подскажите как.
unsigned int a,b,c; ... c=a&(0x000F); //копируем 4 младших бита из числа а, остальные обнуляем c=(c<<11);//сдвигаем их до 14-11 битов b=b&~(0x7800);//сбрасываем 14-11 биты в числе b (здесь ошибка была, забыл проинвертировать, сейчас поправил) b=b|c;//копируем биты из числа с в число b
_________________ Ставим плюсы: )
Последний раз редактировалось ibiza11 Пн янв 17, 2011 01:00:15, всего редактировалось 2 раз(а).
ibiza11 Спасибо. Точно, меня же интересуют 11-14 биты, а они входят в int переменную, значит можно просто с помощью двоичного ИЛИ сложит int и long int (предварительно сдвинув int) и получить желаемое.
Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21 Сообщений: 19675 Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения:0 Медали: 1
dm211 писал(а):
проверил-работает.
Гы, ещё бы оно не работало
_________________ [ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ] Измерить нннада?
int main(int argc,char* argv[]) { int val,port; int fd;
if(argc<3){fprintf(stderr,"usage: %s port value\n",argv[0]); exit(1);} if(sscanf(argv[1],"0x%x",&port) && sscanf(argv[2],"0x%x",&val)) { fd=open("/dev/io",O_RDWR); if(fd==-1){perror("open");exit(1);} outb(port,val); close(fd); } else {fprintf(stderr,"port and value must be in hex format with 0x prefix\n"); exit(1);}
}
ругается на outb.
я опять затеял переписывать программу с паскаля )) я бы и так ею пользовался, но она не работает в wine
_________________ RETI ;рети-рети интеррапт, через шины данных тракт, через память, через порт, возвращайся в главный код @hobbyelectronics
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения