реклама на сайте
подробности

 
 
> Вопрос к знатокам С.
demiurg_spb
сообщение Oct 20 2008, 16:04
Сообщение #1


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Возник тут вопрос.
Кусочек программы можно написать двумя способами,
но с одним и тем же правильным результатом (компилятор avr-gcc 4.1.2).
Вопрос: это можно взять на вооружение?
И что стандарт может нам сказать по этому поводу?
Спасибо.
Код
//============================================
    unsigned char temp;

    temp = *uart->pUDR;   // Очищаем буфер 3-его уровня.
    temp = *uart->pUDR;  
    temp = *uart->pUDR;  

//============================================
    *uart->pUDR;   // Очищаем буфер 3-его уровня.
    *uart->pUDR;  
    *uart->pUDR;


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
7 страниц V  « < 4 5 6 7 >  
Start new topic
Ответов (75 - 89)
zltigo
сообщение Dec 25 2008, 14:06
Сообщение #76


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(defunct @ Dec 25 2008, 16:29) *
Думаю, счетчик отправленных байт должен помочь. Драйвер будет вытаскивать из FIFO ровно то количество байт, которое он запихнул при записи.

Вопрос ведь в том, КУДА ОН ИХ БУДЕТ ДЕВАТЬ после ВЫТАСКИВАНИЯ? Выбрасывать? Вы обещали научить меня писать драйвера
Цитата
.... так, что тупое опустошение не понадобится вовсе!

Если под "умным" опустошением предполагается их, при их априори полной бесполезности тем не менее складывать куда-то дабы "когда свалимся в DABT, можно будет снять дамп и посмотреть", то что тогда назвать безумием smile.gif smile.gif smile.gif
Цитата
будет чуть-чуть дольше, зато интуитивно понятно, что делается.

И дольше и уж абсолютно интуитивно не понятна запись совершенно конкретного нуля, когда на самом деле может быть записано абсолютно произвольное значение sad.gif. В общем это,конечно, мелочи... Но лучше владеть языком так, дабы не было и мелких огрехов, а не уповать на то, что "твоя моя и так понимай если твоя моя понимай однако нада будет".

Цитата(defunct @ Dec 25 2008, 16:29) *
Дело привычки. Например как Вы поступите если есть некий шаблон колбека:
Код
typedef void (*putmsg_cb)(char *, int, int)


и куча функций подпадающих под этот шаблон, но не использующих все параметры?

Мне удобно поступать так:

Код
void xx_putmsg( char *msg, int size, int priority)
{
    ignore( priority ); // <-- избавились от warning'a и сразу видно, что параметр priority нафиг не


Будете смеяться, но мне - удобно АБСОЛЮТНО аналогично smile.gif.
Код
#define argsused(foo) (void)(foo)
argsused( priority );

Только это совсем разные случаи, ибо в описываемый ранее
SPSR;
Абсолютно самодостаточен и не совершенно не нуждается, в отличии от priority, ни в каких мусорных обертках ignore( SPSR ); Если хотите сделать понятным для "танкистов", то напишите комментарий - "танкист" чуть-чуть выглянет из люка и узнает немного нового smile.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Dec 25 2008, 15:32
Сообщение #77


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(zltigo @ Dec 25 2008, 16:06) *
Вопрос ведь в том, КУДА ОН ИХ БУДЕТ ДЕВАТЬ после ВЫТАСКИВАНИЯ? Выбрасывать?

Складывать в кольцевой буфер, и "семафорить - данные есть". Если эти данные хоть кому-то нужны, обрабатывающий процесс их заберет, если не нужны драйвер перетрет их нафиг по кольцу. Но взятки - гладки, свою работу - принять, нативно опустошить, просигналить - драйвер сделал.

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

Это перебор. Я такого не обещал, к тому же Вы и так умеете их писать.
А порассуждать как можно написать драйвер, чтобы избежать пустых чтений - это пожалуйста. smile.gif

Цитата
Если под "умным" опустошением предполагается их, при их априори полной бесполезности тем не менее складывать куда-то дабы "когда свалимся в DABT, можно будет снять дамп и посмотреть", то что тогда назвать безумием smile.gif smile.gif smile.gif

Под "умным" опустошением понимаем - монотонную работу драйвера. Не ему решать что полезно, а что бесполезно. Принимать без разбора драйвер должен абсолютно все, что физически приходит, и отдавать upper layer'у на рассмотрение.

Цитата
Но лучше владеть языком так, дабы не было и мелких огрехов, а не уповать на то, что "твоя моя и так понимай если твоя моя понимай однако нада будет".

Бесспорно. Но, даже при хорошем владении языком, лучше уходить от неоднозначностей там где можно, а там где нет неоднозначностей - подчеркивать логику работы кода:

if (a || b && c)
или
if (a || (b && c) )
вроде одно и то же, но второе ведь наглядней.

Цитата
Будете смеяться, но мне - удобно АБСОЛЮТНО аналогично smile.gif.

Смеяться не буду, - хорошо, что мы на одной волне в этом вопросе smile.gif

Цитата
Только это совсем разные случаи, ибо в описываемый ранее
SPSR;
Абсолютно самодостаточен и не совершенно не нуждается, в отличии от priority

Я бы не был так категоричен. Потому что SPSR - это не переменная, а макрос. Что там за ним спрятано - хз. Скажете, а UM на что, а если его нет под рукой у читателя кода?

Цитата
ни в каких мусорных обертках ignore( SPSR ); Если хотите сделать понятным для "танкистов", то напишите комментарий - "танкист" чуть-чуть выглянет из люка и узнает немного нового smile.gif

шутку понял smile.gif

Но все же
argused()
ignore()
accessed()
и т.п. делают код прозрачнее, и гибче при переносе.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 25 2008, 16:09
Сообщение #78


Гуру
******

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



Цитата(defunct @ Dec 25 2008, 17:32) *
if (a || b && c)
или
if (a || (b && c) )
вроде одно и то же, но второе ведь наглядней.
Это далеко не одно и то же. Логические операции И и ИЛИ всегда выполняются слева направо. Даже компилятор не имеет права изменить этот порядок. Эквивалентным будет if (( a || b ) && c) и со скобками действительно нагляднее.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
defunct
сообщение Dec 25 2008, 16:24
Сообщение #79


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Сергей Борщ @ Dec 25 2008, 18:09) *
Это далеко не одно и то же. Логические операции И и ИЛИ всегда выполняются слева направо. Даже компилятор не имеет права изменить этот порядок. Эквивалентным будет if (( a || b ) && c) и со скобками действительно нагляднее.

А приоритеты операций?

Все-таки
if (a || b && c)
или
if (a || (b && c) )
это одно и то же.
Если есть время, просимулируйте вот этот тестик:
Код
void test(void)
{
   int a = 1;
   int b = 0;
   int c = 0;

   if (a || b && c )
      printf("1 || (0 && 0)");
   else
      printf("(1 || 0) && 0");
}

У меня результат этого теста - "1 || (0 && 0)". (RVDS 2.2 и 3.1).
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 25 2008, 17:09
Сообщение #80


Гуру
******

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



Цитата(defunct @ Dec 25 2008, 18:24) *
А приоритеты операций?

Все-таки
if (a || b && c)
или
if (a || (b && c) )
это одно и то же.
Точно. Приоритеты подзабыл. Решил, что у них одинаковый приоритет. Посыпаю голову окурками.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
defunct
сообщение Dec 25 2008, 17:21
Сообщение #81


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Сергей Борщ @ Dec 25 2008, 19:09) *

Да все в порядке. Как раз хороший пример получился beer.gif - лишний раз подчеркнуть логику работы кода - это только плюс.
Go to the top of the page
 
+Quote Post
ARV
сообщение Dec 27 2008, 13:45
Сообщение #82


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(defunct @ Dec 25 2008, 20:21) *
Да все в порядке. Как раз хороший пример получился beer.gif - лишний раз подчеркнуть логику работы кода - это только плюс.

как-то натолкнулся на высказывание "в Си скобки лишними не бывают" smile.gif понравилось, следую этому правилу постоянно. голова болит меньше и проблем тоже меньше smile.gif


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jan 4 2009, 11:12
Сообщение #83


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(zltigo @ Oct 20 2008, 20:17) *
Поскольку регистры uart безвариантно являются и прописаны как volatile, то несомнено второй вариант, ибо явные промежуточные переменные просто совсем не нужны.

Что-то не получается обойтись без временной переменной.
Вот код:
Код
void    i2cStartRead(dword address)
{
    ...
        //dword    temp = I2C2->SR2;
    I2C2->SR2;
}

на что компилер (RV) ругается: i2c.cpp(71): warning: #174-D: expression has no effect

Тот же самый код разложенный по "полочкам":
Код
typedef volatile unsigned short vu16;
typedef unsigned short u16;

typedef struct
{
  vu16 CR1;
  u16  RESERVED0;
  vu16 CR2;
  u16  RESERVED1;
  vu16 OAR1;
  u16  RESERVED2;
  vu16 OAR2;
  u16  RESERVED3;
  vu16 DR;
  u16  RESERVED4;
  vu16 SR1;
  u16  RESERVED5;
  vu16 SR2;
  u16  RESERVED6;
  vu16 CCR;
  u16  RESERVED7;
  vu16 TRISE;
  u16  RESERVED8;
} I2C_TypeDef;

void    i2cStartRead(dword address)
{
        ...
    ((I2C_TypeDef *) (((u32)0x40000000) + 0x5800))->SR2;
}

Как убрать предупреждение компилятора, и обойтись без явной временной переменной?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 4 2009, 14:31
Сообщение #84


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(sonycman @ Jan 4 2009, 14:12) *
Как убрать предупреждение компилятора, и обойтись без явной временной переменной?

Что-то я совсем не понял, что и как Вы собственно написали sad.gif. А вообще так:
Код
typedef volatile struct
{
    unsigned short SR2;
.....
} I2C_TypeDef;

I2C_TypeDef *I2C2 =  (I2C_TypeDef *)(0x40000000 + 0x5800);

void i2cStartRead(void)
{
....
    I2C2->SR2;

}

P.S.
И вместо мути в структуре ввиде 'reserved' используйте 32bit паковку.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jan 4 2009, 15:42
Сообщение #85


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(zltigo @ Jan 4 2009, 18:31) *
Что-то я совсем не понял, что и как Вы собственно написали sad.gif. А вообще так...

P.S.
И вместо мути в структуре ввиде 'reserved' используйте 32bit паковку.

Так эта муть - библиотека ST для STM32. Я из неё использую только определения регистров.
Ну её нафиг переделывать, и так пришлось править, чтобы хидеры из C++ компилировались... smile.gif

Попробовал, как Вы подсказали:
Код
    typedef volatile struct
{
    int    a;
    int    b;
    unsigned short SR2;

} I2C_Type_Def;
    
    I2C_Type_Def * I2C2_1 =  (I2C_Type_Def *)(0x40000000 + 0x5800);

    I2C2_1->SR2;

но компилятор по-прежнему ругается: main.cpp(26): warning: #174-D: expression has no effect
и выкидывает из кода эту строку... 07.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 4 2009, 16:05
Сообщение #86


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(sonycman @ Jan 4 2009, 18:42) *
чтобы хидеры из C++ компилировались... smile.gif

Так что, плюсовым компилируете!? Так тут уже по моему обсуждалось в начале топика - у плюсового свои странные понятия sad.gif....
А такое, тогда он просто молча выкинет?
(void)I2C2_1->SR2;


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jan 4 2009, 16:22
Сообщение #87


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(sonycman @ Jan 4 2009, 21:42) *
Попробовал, как Вы подсказали:
Код
    typedef volatile struct
{
    int    a;
    int    b;
    unsigned short SR2;

} I2C_Type_Def;
    
    I2C_Type_Def * I2C2_1 =  (I2C_Type_Def *)(0x40000000 + 0x5800);

    I2C2_1->SR2;

но компилятор по-прежнему ругается: main.cpp(26): warning: #174-D: expression has no effect
и выкидывает из кода эту строку... 07.gif

Впервые вижу волатильную структуру smile.gif Может я ошибаюсь, но только переменная может иметь этот атрибут. Попробуйте объявить так:
Код
    (volatile I2C_Type_Def *)(0x40000000 + 0x5800)->SR2;

Потом проверьте есть ли в листинге чтение этого регистра.

Я написал без временной переменной, но если она нужна или надо делать несколько чтений, то можно так:
Код
    volatile I2C_Type_Def * I2C2_1 =  (volatile I2C_Type_Def *)(0x40000000 + 0x5800);

    I2C2_1->SR2;


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 4 2009, 16:27
Сообщение #88


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(GetSmart @ Jan 4 2009, 19:22) *
но только переменная может иметь этот атрибут...

С чего-бы это вдруг, тем более, что сами написали
volatile I2C_Type_Def * I2C2_1
А если хотели
I2C_Type_Def * volatile I2C2_1
так это совсем другое....


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jan 4 2009, 17:05
Сообщение #89


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Jan 4 2009, 22:27) *
С чего-бы это вдруг, тем более, что сами написали
volatile I2C_Type_Def * I2C2_1
А если хотели
I2C_Type_Def * volatile I2C2_1
так это совсем другое....

Не, не. Я правильно выразил свою мысль в кодеsmile.gif
<<volatile I2C_Type_Def *>> говорит, что там, по адресу будет лежать волатильная структура/переменная. Переменная с адресом (I2C2_1) не должна/обязана быть волатильной. Разглядывая чужие хидеры, например из ИАРа, я ни разу не встречал волатил при объявлении структур, а вот при объявлении переменных - всегда. Поэтому и удивился. Если, теоретически, структуры могут иметь этот атрибут, то возможно проблема у sonycman-а в том, что компилятор не учитывает волатил из структуры, но будет учитывать при непосредственном объявлении в переменной. Проверить-то легко.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 4 2009, 17:49
Сообщение #90


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(GetSmart @ Jan 4 2009, 20:05) *
то возможно проблема у sonycman-а в том...

Проблема в том, что компилятор плюсовый.


Цитата(GetSmart @ Jan 4 2009, 20:05) *
<<volatile I2C_Type_Def *>> говорит, что там, по адресу будет лежать волатильная структура...

Угу, только почему-то буквально строчкой выше Вы выражали сомнение в возможности описания таких структур smile.gif. О чем речь я и завел.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

7 страниц V  « < 4 5 6 7 >
Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 08:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01565 секунд с 7
ELECTRONIX ©2004-2016