Перейти к содержанию
    

Вопрос к знатокам С.

Думаю, счетчик отправленных байт должен помочь. Драйвер будет вытаскивать из FIFO ровно то количество байт, которое он запихнул при записи.

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

.... так, что тупое опустошение не понадобится вовсе!

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

будет чуть-чуть дольше, зато интуитивно понятно, что делается.

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

 

Дело привычки. Например как Вы поступите если есть некий шаблон колбека:

typedef void (*putmsg_cb)(char *, int, int)

 

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

 

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

 

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

 

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

#define argsused(foo) (void)(foo)
argsused( priority );

Только это совсем разные случаи, ибо в описываемый ранее

SPSR;

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос ведь в том, КУДА ОН ИХ БУДЕТ ДЕВАТЬ после ВЫТАСКИВАНИЯ? Выбрасывать?

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

 

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

Это перебор. Я такого не обещал, к тому же Вы и так умеете их писать.

А порассуждать как можно написать драйвер, чтобы избежать пустых чтений - это пожалуйста. :)

 

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

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

 

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

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

 

if (a || b && c)

или

if (a || (b && c) )

вроде одно и то же, но второе ведь наглядней.

 

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

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

 

Только это совсем разные случаи, ибо в описываемый ранее

SPSR;

Абсолютно самодостаточен и не совершенно не нуждается, в отличии от priority

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

 

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

шутку понял :)

 

Но все же

argused()

ignore()

accessed()

и т.п. делают код прозрачнее, и гибче при переносе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

if (a || b && c)

или

if (a || (b && c) )

вроде одно и то же, но второе ведь наглядней.

Это далеко не одно и то же. Логические операции И и ИЛИ всегда выполняются слева направо. Даже компилятор не имеет права изменить этот порядок. Эквивалентным будет if (( a || b ) && c) и со скобками действительно нагляднее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это далеко не одно и то же. Логические операции И и ИЛИ всегда выполняются слева направо. Даже компилятор не имеет права изменить этот порядок. Эквивалентным будет 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).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Все-таки

if (a || b && c)

или

if (a || (b && c) )

это одно и то же.

Точно. Приоритеты подзабыл. Решил, что у них одинаковый приоритет. Посыпаю голову окурками.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да все в порядке. Как раз хороший пример получился :beer: - лишний раз подчеркнуть логику работы кода - это только плюс.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да все в порядке. Как раз хороший пример получился :beer: - лишний раз подчеркнуть логику работы кода - это только плюс.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поскольку регистры 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;
}

Как убрать предупреждение компилятора, и обойтись без явной временной переменной?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как убрать предупреждение компилятора, и обойтись без явной временной переменной?

Что-то я совсем не понял, что и как Вы собственно написали :(. А вообще так:

typedef volatile struct
{
    unsigned short SR2;
.....
} I2C_TypeDef;

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

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

}

P.S.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то я совсем не понял, что и как Вы собственно написали :(. А вообще так...

 

P.S.

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

Так эта муть - библиотека ST для STM32. Я из неё использую только определения регистров.

Ну её нафиг переделывать, и так пришлось править, чтобы хидеры из C++ компилировались... :)

 

Попробовал, как Вы подсказали:

    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:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

чтобы хидеры из C++ компилировались... :)

Так что, плюсовым компилируете!? Так тут уже по моему обсуждалось в начале топика - у плюсового свои странные понятия :(....

А такое, тогда он просто молча выкинет?

(void)I2C2_1->SR2;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробовал, как Вы подсказали:

    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:

Впервые вижу волатильную структуру :) Может я ошибаюсь, но только переменная может иметь этот атрибут. Попробуйте объявить так:

    (volatile I2C_Type_Def *)(0x40000000 + 0x5800)->SR2;

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

 

Я написал без временной переменной, но если она нужна или надо делать несколько чтений, то можно так:

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

    I2C2_1->SR2;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но только переменная может иметь этот атрибут...

С чего-бы это вдруг, тем более, что сами написали

volatile I2C_Type_Def * I2C2_1

А если хотели

I2C_Type_Def * volatile I2C2_1

так это совсем другое....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С чего-бы это вдруг, тем более, что сами написали

volatile I2C_Type_Def * I2C2_1

А если хотели

I2C_Type_Def * volatile I2C2_1

так это совсем другое....

Не, не. Я правильно выразил свою мысль в коде:)

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

то возможно проблема у sonycman-а в том...

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

 

 

<<volatile I2C_Type_Def *>> говорит, что там, по адресу будет лежать волатильная структура...

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...