Например TDA7294

Форум РадиоКот • Просмотр темы - Вопросы по С/С++ (СИ)
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Сб июн 28, 2025 17:35:30

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 7669 ]     ... , , , 9, , , ...  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс янв 02, 2011 00:43:02 
Встал на лапы

Зарегистрирован: Вс мар 01, 2009 20:41:19
Сообщений: 125
Рейтинг сообщения: 0
разобрался =)
Код:
#if DOXYGEN || LITTLE_ENDIAN || __AVR__
#define HTOL16(val) (val)
#define HTOL32(val) (val)
#elif BIG_ENDIAN
#define HTOL16(val) ((((uint16_t) (val)) << 8) | \
                     (((uint16_t) (val)) >> 8)   \
                    )
#define HTOL32(val) (((((uint32_t) (val)) & 0x000000ff) << 24) | \
                     ((((uint32_t) (val)) & 0x0000ff00) <<  8) | \
                     ((((uint32_t) (val)) & 0x00ff0000) >>  8) | \
                     ((((uint32_t) (val)) & 0xff000000) >> 24)   \
                    )
//**********IAR**************************************************** 
#elif DOXYGEN || __LITTLE_ENDIAN__ || __AVR__
#define HTOL16(val) (val)
#define HTOL32(val) (val)
#elif __BIG_ENDIAN__
#define HTOL16(val) ((((uint16_t) (val)) << 8) | \
                     (((uint16_t) (val)) >> 8)   \
                    )
#define HTOL32(val) (((((uint32_t) (val)) & 0x000000ff) << 24) | \
                     ((((uint32_t) (val)) & 0x0000ff00) <<  8) | \
                     ((((uint32_t) (val)) & 0x00ff0000) >>  8) | \
                     ((((uint32_t) (val)) & 0xff000000) >> 24)   \
                    ) 
//******************************************************************* 
 
 
#else
#error "Endianess undefined! Please define LITTLE_ENDIAN=1 or BIG_ENDIAN=1."
#endif


в иар __LITTLE_ENDIAN__ в GNUC LITTLE_ENDIAN


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс янв 02, 2011 01:01:52 
Грызет канифоль
Аватар пользователя

Карма: 1
Рейтинг сообщений: 4
Зарегистрирован: Пн окт 25, 2010 20:47:04
Сообщений: 271
Откуда: Казахстан, Астана
Рейтинг сообщения: 0
ARV писал(а):
shurikss123 писал(а):
Всех с наступившим новым годом.

подскажите пожл. как мне конвертировать HEX 0x08e6 в DEC 2278.

пробывал всякие bcd2dec bin2dec, результат не тот
а вообще я радио мучу там формула такая
Код:
           
ra=0x08e6;//dec-2278
temp=ra;
temp=temp*50;//dec-113900
temp=(temp-10700);//dec-103200-103,2 fm

все работает, ток вот на дисплей нормально инфу ввывести не могу

например, так:
Код:
printf("%d",ra);
:)))
вы не путайте присваивание значения в шестнадцатеричном формате с самим числом...


Как раз число мне и нужно, чтоб я его умножил, отнял, и получил, нужное значение волны.

_________________
Изображение
Мастер на все руки, кручу, кручу, кручу и матерюсь
Повелитель паяльной станции, лома, и пинцета!!!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вс янв 02, 2011 15:37:44 
Грызет канифоль
Аватар пользователя

Карма: 1
Рейтинг сообщений: 4
Зарегистрирован: Пн окт 25, 2010 20:47:04
Сообщений: 271
Откуда: Казахстан, Астана
Рейтинг сообщения: 0
shurikss123 писал(а):
ARV писал(а):
shurikss123 писал(а):
Всех с наступившим новым годом.

подскажите пожл. как мне конвертировать HEX 0x08e6 в DEC 2278.

пробывал всякие bcd2dec bin2dec, результат не тот
а вообще я радио мучу там формула такая
Код:
           
ra=0x08e6;//dec-2278
temp=ra;
temp=temp*50;//dec-113900
temp=(temp-10700);//dec-103200-103,2 fm

все работает, ток вот на дисплей нормально инфу ввывести не могу

например, так:
Код:
printf("%d",ra);
:)))
вы не путайте присваивание значения в шестнадцатеричном формате с самим числом...



Как раз число мне и нужно, чтоб я его умножил, отнял, и получил, нужное значение волны.


Все решил проблему с помошью первой главы книги!!
просто когда делал умножение переменнная(unsigned long int) переполнялась и число было другим, зделал(uint32_t) все сразу заработало
Код:
uint32_t temp,res;
uint16_t ra=0x08e6; //2278
temp=ra;
temp=(temp*50)-10700; //2278*50=113900-10700=103200;

res=temp/100000; //103200/100000=1,032
LCDsendChar(digi[res]);// print 1
temp=temp-res*100000;

res=temp/10000;
LCDsendChar(digi[res]);print 0
temp=temp-res*10000;

res=temp/1000;
LCDsendChar(digi[res]); print 3
temp=temp-res*1000;

_________________
Изображение
Мастер на все руки, кручу, кручу, кручу и матерюсь
Повелитель паяльной станции, лома, и пинцета!!!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вт янв 11, 2011 02:43:34 
Вымогатель припоя

Карма: 2
Рейтинг сообщений: 2
Зарегистрирован: Пн мар 23, 2009 04:03:45
Сообщений: 557
Рейтинг сообщения: 0
Товарищи, хелп! Кончилась память в контроллере, пришло время оптимизировать код :cry: Начать решил с того, что сразу в глаза бросается неадекватным размером и кривостью:
Код:
#define RX_BIN_BUFSIZE   40
//.....
volatile unsigned char rxBinBuffer [RX_BIN_BUFSIZE]; //Имеется буфер для приема данных из UART
//.....
volatile signed long int time;                             //Имеется 32-битная переменная
//В буфер принимаются данные с компа, и в позициях rxBinBuffer[3]...rxBinBuffer[6]
//старшим байтом "кверху" лежит 32-битное число, которое хотелось бы присвоить переменной.
//Компилятор переменные long int располагает в памяти данных старшим байтом "вниз".
//В общем, мой код:
time = ((long int) rxBinBuffer[3] << 24) + ((long int) rxBinBuffer[4] << 16) +
         ((int) rxBinBuffer[5] << 8 ) + rxBinBuffer[6] ;

Компилируется это естественно в черт знает что, где-то на 100 инструкций размером. Научите, как правильно сделать без ассемблерных вставок (этот козырь я пока решил поберечь 8) ). Не стреляйте в программиста, он пишет как умеет :oops:


Вернуться наверх
 
Выбираем индустриальные и медицинские источники питания MEAN WELL в открытом исполнении

Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вт янв 11, 2011 08:08:08 
Опытный кот
Аватар пользователя

Зарегистрирован: Вс янв 18, 2009 21:12:49
Сообщений: 703
Рейтинг сообщения: 0
2stas00n, например, через UNION структуру код должен уменьшиться. Смотреть надо компиленный asm.
А вообще то, компилятор на volatile действия в одну строку должен был ругнуться.
Код:
#define RX_BIN_BUFSIZE   40
volatile unsigned char rxBinBuffer [RX_BIN_BUFSIZE]; //Имеется буфер для приема данных из UART

typedef union
{
    struct
    {
        unsigned char Byte4;
        unsigned char Byte3;
        unsigned char Byte2;
        unsigned char Byte1;
    };
   
    signed long int LongAll;
} MyTime_t;

volatile MyTime_t mytime;

void main( void )
{
    mytime.Byte1 = rxBinBuffer[3];
    mytime.Byte2 = rxBinBuffer[4];
    mytime.Byte3 = rxBinBuffer[5];
    mytime.Byte4 = rxBinBuffer[6];

    //функция выдумана )
    set_time( mytime.LongAll );
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вт янв 11, 2011 13:38:17 
Вымогатель припоя

Карма: 2
Рейтинг сообщений: 2
Зарегистрирован: Пн мар 23, 2009 04:03:45
Сообщений: 557
Рейтинг сообщения: 0
asteroid7, спасибо, вечером попробую. А что значит
asteroid7 писал(а):
компилятор на volatile действия в одну строку должен был ругнуться
? На какую именно строчку должен ругаться? У меня не ругается, может надо настроить варнинги?. Компилятор hi-tech PICC.


Вернуться наверх
 
Распродажа паяльного оборудования ATTEN!
Паяльные станции, паяльники и аксессуары по самой выгодной цене.

По промокоду radiokot скидка 10%
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вт янв 11, 2011 17:54:02 
Опытный кот
Аватар пользователя

Карма: 7
Рейтинг сообщений: 52
Зарегистрирован: Чт дек 31, 2009 19:27:45
Сообщений: 842
Откуда: Бровари, Україна
Рейтинг сообщения: 0
На ту, где в длинном выражении идёт считывание нескольких volatile-переменных.

Зависит от "тщательности" компилятора и выбранного урованя _предупреждений_ (ошибки там нет).
По стандарту компилятор имеет право зачитывать переменные из памяти в произвольном порядке, но для volatile он обязан соблюдвать заданный порядок.
А тут порядок никак не определён и он ворчит, что результат может зависеть от порядка чтения. Он же не знает, влияет ли чтение buf[7] на содержимое buf[5] с volatile может происходить что угодно :-)

_________________
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вт янв 11, 2011 22:22:28 
Опытный кот
Аватар пользователя

Зарегистрирован: Вс янв 18, 2009 21:12:49
Сообщений: 703
Рейтинг сообщения: 0
stas00n писал(а):
...На какую именно строчку должен ругаться? У меня не ругается, может надо настроить варнинги?. Компилятор hi-tech PICC.
Любое предупреждение компилятора я считаю руганью. Рекомендую включить все предупреждения.

---

Не соглашусь с avreal в высказывании (ошибки там нет).
Нет синтаксической ошибки. Да. Согласен.
Но! Есть очень гадкая логическая ошибка!

Попытаюсь обосновать:
8-и битный компилятор (это тот, который за "такт/раз" умеет считывать только один байт) используя много байтовые глобальные переменные может считать и обработать на следующем "такте/разе" уже искажённые данные.
Т.е., на момент считывания одного из байтов много байтовой переменной другие байты этой переменной, из-за ключевого слова volatile, могут быть легко изменены. А так как, volatile, используется в основном в прерываниях, то, прервав вычисления, это прерывание может такую свинью подложить, что не передать словами… )
Уфф... )))

Выхода два. Считать во временную переменную или запретить все прерывания на момент обработки.

И да. Не сочтите за пиар. Компилятор IAR делает в таких местах предупреждение.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Вт янв 11, 2011 22:59:16 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
OFFTOPIC: IAR обалденный компилятор!!!!! : )


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Ср янв 12, 2011 00:29:40 
Вымогатель припоя

Карма: 2
Рейтинг сообщений: 2
Зарегистрирован: Пн мар 23, 2009 04:03:45
Сообщений: 557
Рейтинг сообщения: 0
asteroid7 писал(а):
А так как, volatile, используется в основном в прерываниях, то, прервав вычисления, это прерывание может такую свинью подложить, что не передать словами… )
Уфф... )))

Упс, как-то я этот момент упустил. У меня time_t инкрементируется каждую секунду в прерывании от TMR1, а когда девайс подключен к компу, время синхронизируется с компьютерными часами через UART по нажатию кнопки в программе на ПК. Если "удачно" подловить момент для синхронизации, действительно глюк можно словить. Запрещу-ка я прерывание на время работы с time_t... asteroid7, avreal спасибо за науку, буду внимательней теперь.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Ср янв 12, 2011 19:34:35 
Опытный кот
Аватар пользователя

Карма: 7
Рейтинг сообщений: 52
Зарегистрирован: Чт дек 31, 2009 19:27:45
Сообщений: 842
Откуда: Бровари, Україна
Рейтинг сообщения: 0
asteroid7 писал(а):
Не соглашусь с avreal в высказывании (ошибки там нет).
...
И да. Не сочтите за пиар. Компилятор IAR делает в таких местах предупреждение.
GCC тоже предупреждение, именно это я и имел ввиду, когда говорил, что ошибки там нет.
Компилятор не знает, есть ли зависимость от порядка чтения этих переменных, как, например, для половинок таймера TCNT1H/TCNT1L. volatile говорит ему только о том, что он а) обязан зачитать, даже если "только что" читал, б) не должен менять порядок обращений. И тут он предупрежадет о том, что не знает, какой порядок должен быть, скомпилировал как пришлось, а программист пусть разбирается. Может, порядок и не важен. Точка.

asteroid7 писал(а):
Нет синтаксической ошибки. Да. Согласен.
Но! Есть очень гадкая логическая ошибка!

Попытаюсь обосновать:
8-и битный компилятор (это тот, который за "такт/раз" умеет считывать только один байт) используя много байтовые глобальные переменные может считать и обработать на следующем "такте/разе" уже искажённые данные.
...
Выхода два. Считать во временную переменную или запретить все прерывания на момент обработки
Выход один - запретить прерывания. На время обработки или на время считывания во временную переменную — не важно. Второе время меньше, значит, вероятность глюка при незапрещённых прерываниях меньше, значит, глюк не будет отловлен на столе и будет заработана беда на задницу после установки изделия на объект.
Логические ошибки программиста компилятор вылавливать не обязан. Это раз.
Два — описываемая Вами проблема будет и при обращении к одной переменной (а не к нескольким, как для обсуждаемого предупреждения). И компилятор даже предупреждения не выдаст. Компилятор не знает — запрещены ли прерывания (например, ещё в функции уровнем выше) вообще, запрещено ли именно то прерывание, которое может помешать и т.д. и т.п. И вообще он не знает, что данный volatile зависит именно от прерывания. Может, то аппаратный регистр. Вон для упомянутых выше половинок TCNT аппаратура обеспечивает защёлкивание двухбайтовой переменной, нужно только в правильном порядке читать (там для не-xmega опять может вылезть беда, если прерывание обращается к другому словному регистру AVR, но это, опять-таки, компилятору не ведомо).
Проблема считывания/записи "многобайтных" переменных (проблема критических секций) это нечто параллельное и независимое. И не специфически-8-битное, так как и у 32-битного процессора бывают 64-битные переменные, и вообще нужным значением может быть структура из нескольких полей, когерентность которых важна. Описываемая бяка будет и с uint8_t;
Код:
volatile uint8_t a;
volatile uint8_t b;

void wait_ab() { while( a != b )  ;  }
будет то же самое предупреждение о порядке считывание volatile-переменных. Уйти от него можно при помощи
Код:
volatile uint8_t a;
volatile uint8_t b;
void wait_ab()
{
    uint8_t temp;
    do {
        temp = a;
    } while( temp != b);
}
Критические секции, ATOMIC_BLOCKS() и тому подобное - это само собой, volatile не спасает от проблем многоциклового доступа. Для типов, которые не читаются/не пишутся за один раз, атомарность надо обеспечивать вручную. Кстати, поэтому во многих компиляторах в signal.h определён тип sig_atomic_t, это максимальный размер целого, для которого гарантируется атомарное обращение.

_________________
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Ср янв 12, 2011 19:42:35 
Опытный кот
Аватар пользователя

Карма: 7
Рейтинг сообщений: 52
Зарегистрирован: Чт дек 31, 2009 19:27:45
Сообщений: 842
Откуда: Бровари, Україна
Рейтинг сообщения: 0
P.S. "не сочтите за пиар" - у avr-gcc есть очень хороший atomic.h, полный аналог которому, насколько я знаю, мало для какого компилятора (если рассматривать только С, без С++) можно написать.
Код:
   ATOMIC_BLOCK(тип_блока) {
      все операторы тут будут выполняться при нужном состоянии прерываний
      запрещены -- потом разрешены либо сохранено состояние, запрещены, потом восстановлено
      из блока можно выходить по return, по goto -- всё равно отработает правильно
  }

_________________
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Ср янв 12, 2011 22:16:14 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
Подскажите кто знает, почему не выводится сообщение при компиляции проекта?
Код:
#include stdio.h
....
#pragma message("_Test message_")

компилятор IAR AVR. Подозреваю проблема связана с stdio библиотекой, но вроде ее хеадер я подключил в начале проекта...

PS Хочу использовать эту фичу для контроля значений основных объявленных констант (они у меня пересчитываются препроцессором, поэтому было бы очень удобно)
Если нет ответа, тогда подскажите, как можно реализовать что-нибудь подобное?

_________________
Ставим плюсы: )


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Чт янв 13, 2011 09:04:34 
Опытный кот
Аватар пользователя

Зарегистрирован: Вс янв 18, 2009 21:12:49
Сообщений: 703
Рейтинг сообщения: 0
avreal писал(а):
GCC тоже предупреждение, именно это я и имел ввиду, когда говорил, что ошибки там нет.
Согласитесь, что в выше случае компилятор делает предупреждение о возможной логической ошибке.
Ещё пример, где нет ошибки, но есть предупреждение:
Код:
    char c;
    if ( c = 2 ) { ... }


Я в предыдущем посте не точно указал про два варианта. Правильнее, при считывании во временную переменную необходимо тоже запретить прерывания на момент считывания, а потом спокойно с ней работать. И второй - на все вычисления запретить. Спасибо, что поправили.

---

Будет свободное время посмотрю atomic.h для GCC. В IAR-e видел похожее на критические секции сделанные через классы, но применять не довелось. Для AVR обходился простым
Код:
   U8 sreg = SREG;
   CLI;     // ЗАБЫЛ ЕЁ ДОБАВИТЬ ))))
   //крит. секция
   ...
   SREG = sreg;


забыл CLI вставить )


Последний раз редактировалось asteroid7 Чт янв 13, 2011 09:47:26, всего редактировалось 1 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Чт янв 13, 2011 09:12:33 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 98
Рейтинг сообщений: 2116
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18398
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
asteroid7 писал(а):
Для AVR обходился простым
Код:
   U8 sreg = SREG;
   //крит. секция
   ...
   SREG = sreg;
ну, наверное, все-таки вы делали так:
Код:
   U8 sreg = SREG;
   cli(); // без этого никакого смысла нет в критической секции
   //крит. секция
   ...
   SREG = sreg;

но проблемы начнутся, если в критической секции есть return или критическая секция в цикле и в ней есть break - тогда ваш способ обрастает всякими проверками для правильного восстановления SREG в нужный момент и т.д. - кайф пропадает. а в atomic.h макрос ATOMIC_BLOCK позволяет об этом не думать - SREG всегда будет верно восстановлен, и при этом практически не будет избыточного кода.

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Чт янв 13, 2011 09:21:37 
Опытный кот
Аватар пользователя

Зарегистрирован: Вс янв 18, 2009 21:12:49
Сообщений: 703
Рейтинг сообщения: 0
ibiza11 писал(а):
Подскажите кто знает, почему не выводится сообщение при компиляции проекта?

Оно выводится в окно "Build". А настройки Tools->Options->Messages->Show Build стоит в All или Messages ?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Чт янв 13, 2011 09:30:06 
Опытный кот

Карма: 5
Рейтинг сообщений: 0
Зарегистрирован: Вс янв 17, 2010 15:32:19
Сообщений: 701
Откуда: Курган
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
просттите за глупый вопрос. если прерывание должно возникнуть, когда они запрещены, то после их разрешения оно сгенерируется?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Чт янв 13, 2011 09:30:51 
Опытный кот
Аватар пользователя

Зарегистрирован: Вс янв 18, 2009 21:12:49
Сообщений: 703
Рейтинг сообщения: 0
ARV писал(а):
но проблемы начнутся, если в критической секции есть return или критическая секция в цикле и в ней есть break ...
Обычно, код критической секции линейный. Простые чтение/запись Eeprom-a, по SPI чё нить оправить/принять, volatile переменные обработать. С ветвлениями в таких местах программы не сталкивался.

ARV писал(а):
макрос ATOMIC_BLOCK позволяет об этом не думать - SREG всегда будет верно восстановлен, и при этом практически не будет избыточного кода.
Теперь точно найду время на изучение хидеров GCC )


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Чт янв 13, 2011 10:05:31 
Опытный кот
Аватар пользователя

Карма: 7
Рейтинг сообщений: 52
Зарегистрирован: Чт дек 31, 2009 19:27:45
Сообщений: 842
Откуда: Бровари, Україна
Рейтинг сообщения: 0
asteroid7 писал(а):
Согласитесь, что в выше случае компилятор делает предупреждение о возможной логической ошибке.
Ещё пример, где нет ошибки, но есть предупреждение:
Код:
    char c;
    if ( c = 2 ) { ... }
Это как раз специально-для-забывчивых введённое предупреждение. Компилятор эту строку инетрпретирует однозначно, но надстройка переспрашивает. Зачатки искусственного интелекта, когда-то компилятор, может, и начнет компилировать то, что программист хотел написать, а не то, что он дейстивтельно написал. Вот счастье-то будет для не читающих документацию на язык и на контроллер...
А обсуждаемое предупреждение — о том, что компилятор не может понять однозначно. Это совершенно по сути разные предупреждения. Если бы у компилятора было разделение на «critical warning» и «informative warning», то обсуждаемое предупреждение было бы critical, а про if( c = 2) — informative.
В обсуждаемом случае компилятору стандарт сказал, что он не должен менять порядок обращений к volatile, а программист порядок не задал. Когнитивный диссонанс.
А вот пример, где логическая ошибка может быть для _любой_ архитектуры (хоть 128-битной), а предупреждения нет.
Код:
volatile char a;
volatile char b;
bool foo()
{
    char ta = a;
    return ta == b;
}


asteroid7 писал(а):
Будет свободное время посмотрю atomic.h для GCC. В IAR-e видел похожее на критические секции сделанные через классы, но применять не довелось.
Ну так я же сразу сказал, если оставаться в рамках С. Для С++ — без проблем.
Код:
class TCritSect {
public:
    TCritSect() : sreg(SREG) { cli(); }
    ~TCritSect() { SREG = sreg; }
private:
    uint8_t sreg;
};
volatile uint8_t a, b, c;
void foo()
{
    TCritSect cs;
    if( ++a < 20)  return;
    a = 0;
    if( ++b < 20)  return;
    b = 0;
    if( ++c < 20)  return;
    c = 0;
}
почти эквивлентно
Код:
#include <util/atomic.h>
volatile uint8_t a, b, c;
void foo()
{
    ATOMIC_BLOCK(ATOMIC_RESTORSTATE) {
        if( ++a < 20)  return; // а ещё тут можно было написать break для выхода из этого блока
        a = 0;
        if( ++b < 20)  return;
        b = 0;
        if( ++c < 20)  return;
        c = 0;
    }
}
и в большинстве случаев компилируется в тождественный код. И это не удивительно, так как atomic.h использует gcc-шные аттрибуты переменной, которые эквивалентны конструкторам/деструкторам для конкретно этой переменной.
По поводу невыхода из середины критической секции — да, можно написать
Код:
void foo()
{
    uint8_t sreg = SREG;
    cli();
    if( ++a >= 20) {
        a = 0;
        if( ++b >= 20)  {
            b = 0;
            if( ++c < 20)  {
                c = 0;
            }
        }
    }
    SREG = sreg;
}
но мне это кажется более корявым. Когда идёт связанный доступ к нескольким volatile-переменным (например, указатели/индексы головы и хвоста кольцевого буфера и сам буфер), часто код становится гораздо читабельнее, если сделать выход в удобной точке, а не городить каскадные if ради единственного выхода из функции.

_________________
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Вопросы по С/С++ (СИ)
СообщениеДобавлено: Чт янв 13, 2011 12:20:29 
Друг Кота
Аватар пользователя

Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21
Сообщений: 19672
Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
lix писал(а):
просттите за глупый вопрос. если прерывание должно возникнуть, когда они запрещены, то после их разрешения оно сгенерируется?

На мой взгляд, к СИ это не относится, но всё же...
Да, после разрешения прерываний оно возникнет. Если, конечно, программно не сброшен флаг произошедшего прерывания.

_________________
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Измерить нннада?


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 7669 ]     ... , , , 9, , , ...  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: kotneko и гости: 8


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y