|
|
  |
Вопрос к знатокам С. |
|
|
|
Dec 25 2008, 14:06
|

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

|
Цитата(defunct @ Dec 25 2008, 16:29)  Думаю, счетчик отправленных байт должен помочь. Драйвер будет вытаскивать из FIFO ровно то количество байт, которое он запихнул при записи. Вопрос ведь в том, КУДА ОН ИХ БУДЕТ ДЕВАТЬ после ВЫТАСКИВАНИЯ? Выбрасывать? Вы обещали научить меня писать драйвера Цитата .... так, что тупое опустошение не понадобится вовсе! Если под "умным" опустошением предполагается их, при их априори полной бесполезности тем не менее складывать куда-то дабы "когда свалимся в DABT, можно будет снять дамп и посмотреть", то что тогда назвать безумием Цитата будет чуть-чуть дольше, зато интуитивно понятно, что делается. И дольше и уж абсолютно интуитивно не понятна запись совершенно конкретного нуля, когда на самом деле может быть записано абсолютно произвольное значение  . В общем это,конечно, мелочи... Но лучше владеть языком так, дабы не было и мелких огрехов, а не уповать на то, что "твоя моя и так понимай если твоя моя понимай однако нада будет". Цитата(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 нафиг не Будете смеяться, но мне - удобно АБСОЛЮТНО аналогично  . Код #define argsused(foo) (void)(foo) argsused( priority ); Только это совсем разные случаи, ибо в описываемый ранее SPSR; Абсолютно самодостаточен и не совершенно не нуждается, в отличии от priority, ни в каких мусорных обертках ignore( SPSR ); Если хотите сделать понятным для "танкистов", то напишите комментарий - "танкист" чуть-чуть выглянет из люка и узнает немного нового
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 25 2008, 15:32
|

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

|
Цитата(zltigo @ Dec 25 2008, 16:06)  Вопрос ведь в том, КУДА ОН ИХ БУДЕТ ДЕВАТЬ после ВЫТАСКИВАНИЯ? Выбрасывать? Складывать в кольцевой буфер, и "семафорить - данные есть". Если эти данные хоть кому-то нужны, обрабатывающий процесс их заберет, если не нужны драйвер перетрет их нафиг по кольцу. Но взятки - гладки, свою работу - принять, нативно опустошить, просигналить - драйвер сделал. Цитата Вы обещали научить меня писать драйвера Это перебор. Я такого не обещал, к тому же Вы и так умеете их писать. А порассуждать как можно написать драйвер, чтобы избежать пустых чтений - это пожалуйста.  Цитата Если под "умным" опустошением предполагается их, при их априори полной бесполезности тем не менее складывать куда-то дабы "когда свалимся в DABT, можно будет снять дамп и посмотреть", то что тогда назвать безумием  Под "умным" опустошением понимаем - монотонную работу драйвера. Не ему решать что полезно, а что бесполезно. Принимать без разбора драйвер должен абсолютно все, что физически приходит, и отдавать upper layer'у на рассмотрение. Цитата Но лучше владеть языком так, дабы не было и мелких огрехов, а не уповать на то, что "твоя моя и так понимай если твоя моя понимай однако нада будет". Бесспорно. Но, даже при хорошем владении языком, лучше уходить от неоднозначностей там где можно, а там где нет неоднозначностей - подчеркивать логику работы кода: if (a || b && c) или if (a || (b && c) ) вроде одно и то же, но второе ведь наглядней. Цитата Будете смеяться, но мне - удобно АБСОЛЮТНО аналогично  . Смеяться не буду, - хорошо, что мы на одной волне в этом вопросе  Цитата Только это совсем разные случаи, ибо в описываемый ранее SPSR; Абсолютно самодостаточен и не совершенно не нуждается, в отличии от priority Я бы не был так категоричен. Потому что SPSR - это не переменная, а макрос. Что там за ним спрятано - хз. Скажете, а UM на что, а если его нет под рукой у читателя кода? Цитата ни в каких мусорных обертках ignore( SPSR ); Если хотите сделать понятным для "танкистов", то напишите комментарий - "танкист" чуть-чуть выглянет из люка и узнает немного нового  шутку понял Но все же argused() ignore() accessed() и т.п. делают код прозрачнее, и гибче при переносе.
|
|
|
|
|
Dec 25 2008, 16:09
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Dec 25 2008, 16:24
|

кекс
     
Группа: Свой
Сообщений: 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).
|
|
|
|
|
Jan 4 2009, 11:12
|

Любитель
    
Группа: Свой
Сообщений: 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; } Как убрать предупреждение компилятора, и обойтись без явной временной переменной?
|
|
|
|
|
Jan 4 2009, 14:31
|

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

|
Цитата(sonycman @ Jan 4 2009, 14:12)  Как убрать предупреждение компилятора, и обойтись без явной временной переменной? Что-то я совсем не понял, что и как Вы собственно написали  . А вообще так: Код 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
|
|
|
|
|
Jan 4 2009, 15:42
|

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

|
Цитата(zltigo @ Jan 4 2009, 18:31)  Что-то я совсем не понял, что и как Вы собственно написали  . А вообще так... 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 и выкидывает из кода эту строку...
|
|
|
|
|
Jan 4 2009, 16:22
|
.
     
Группа: Участник
Сообщений: 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 и выкидывает из кода эту строку...  Впервые вижу волатильную структуру  Может я ошибаюсь, но только переменная может иметь этот атрибут. Попробуйте объявить так: Код (volatile I2C_Type_Def *)(0x40000000 + 0x5800)->SR2; Потом проверьте есть ли в листинге чтение этого регистра. Я написал без временной переменной, но если она нужна или надо делать несколько чтений, то можно так: Код volatile I2C_Type_Def * I2C2_1 = (volatile I2C_Type_Def *)(0x40000000 + 0x5800);
I2C2_1->SR2;
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 4 2009, 16:27
|

Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Jan 4 2009, 17:05
|
.
     
Группа: Участник
Сообщений: 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 так это совсем другое.... Не, не. Я правильно выразил свою мысль в коде  <<volatile I2C_Type_Def *>> говорит, что там, по адресу будет лежать волатильная структура/переменная. Переменная с адресом (I2C2_1) не должна/обязана быть волатильной. Разглядывая чужие хидеры, например из ИАРа, я ни разу не встречал волатил при объявлении структур, а вот при объявлении переменных - всегда. Поэтому и удивился. Если, теоретически, структуры могут иметь этот атрибут, то возможно проблема у sonycman-а в том, что компилятор не учитывает волатил из структуры, но будет учитывать при непосредственном объявлении в переменной. Проверить-то легко.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 4 2009, 17:49
|

Гуру
     
Группа: Свой
Сообщений: 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 *>> говорит, что там, по адресу будет лежать волатильная структура... Угу, только почему-то буквально строчкой выше Вы выражали сомнение в возможности описания таких структур  . О чем речь я и завел.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
  |
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0
|
|
|