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

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> возможно ли на Си, объединить биты регистров портов микроконтроллера
another_one
сообщение Jun 13 2009, 16:50
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 252
Регистрация: 2-03-08
Пользователь №: 35 557



Здравствуйте.

Прошу подсказки.

С целью удобства и лучшей читабельности необходимо объединить биты портов микроконтроллера в один структурный тип или объединение.

Биты находятся в разных портах и не последовательно.

Не пойму как назначить адрес бита порта к "битовому типу" структуры.

Заранее благодарен


--------------------
One Chip is All You Need
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 13 2009, 17:59
Сообщение #2


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Никак
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Jun 13 2009, 19:38
Сообщение #3


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Вы всегда смотрите, как именно ваши фантазии будет реализовыватcя на данной системе команд. Имеет ли смысл?


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
another_one
сообщение Jun 13 2009, 22:17
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 252
Регистрация: 2-03-08
Пользователь №: 35 557



Цитата(DpInRock @ Jun 13 2009, 23:38) *
Вы всегда смотрите, как именно ваши фантазии будет реализовыватcя на данной системе команд. Имеет ли смысл?

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

Я как -то делал для одного порта - присваивал структуре адрес регистра саециального назначения с помощью директивы #byte в компиляторе CCS для пиков.

Сейчас задача для нека, используя ИАР


--------------------
One Chip is All You Need
Go to the top of the page
 
+Quote Post
SSerge
сообщение Jun 13 2009, 22:49
Сообщение #5


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

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Для читаемости можно оформить доступ к битам в разных портах как макрос примерно так:

#define OUT(x) do{код доступа к битам в разных портах }while(0)

такая конструкция хороша тем, что синтаксически эквивалентна одному оператору и её можно использовать привычным для С образом не рискуя нарваться на маловразумительные сообщения об ошибках.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 00:20
Сообщение #6


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Почитайте современные книги, которые всячески советуют избегать везде, где только можно, макро. Это грабли, приводящие очень часто к трудно вылавливаемым ошибкам.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 14 2009, 05:17
Сообщение #7


Гуру
******

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



Цитата(sergeeff @ Jun 14 2009, 03:20) *
Почитайте современные книги.....

Прости, господи sad.gif, а может просто надо не только "читать современные книги", но и читать просто книги, и просто думать, когда пишешь? Причем пишешь не только макросы, а то возникнут "грабли".


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Herz
сообщение Jun 14 2009, 06:47
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 10 983
Регистрация: 23-11-05
Пользователь №: 11 287



Цитата(sergeeff @ Jun 14 2009, 02:20) *
Почитайте современные книги, которые всячески советуют избегать везде, где только можно, макро. Это грабли, приводящие очень часто к трудно вылавливаемым ошибкам.

Такие книжки читать как раз не нужно, ИМХО. Ибо это из категории вредных советов. biggrin.gif
Go to the top of the page
 
+Quote Post
SSerge
сообщение Jun 14 2009, 10:21
Сообщение #9


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

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Цитата(Herz @ Jun 14 2009, 12:47) *
Такие книжки читать как раз не нужно, ИМХО. Ибо это из категории вредных советов. biggrin.gif

Да нет, сами по себе советы вместо #define использовать const и темплейты - правильные.
Просто в тех книгах речь идёт о С++ и типичных его применениях - для ваяния многомегабайтных монстров. А тут случай практически противоположный - манипуляции битами на самом нижнем уровне, никакой переносимости не требуется по определению, зато важна эффективность.
Но, разумеется, хотелось бы собрать в одном месте все зависимости от номеров битов в портах, чтобы при правках не искать их по всей программе.

Альтернатива - написать пару функций для чтения и для записи, а для эффективности инлайнить их.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 10:27
Сообщение #10


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Мне представляется, что:
1. Есть программисты - одиночки, пишущие и поддерживающие проект самостоятельно.
2. Программисты, либо работающие в коллективе разработчиков, либо вынужденные учитывать тот факт, что их проект может/будет сопровождаться и развиваться другими людьми.

Соответственно подходы к написанию программ сильно разнятся и использование в текстах неочевидных конструкций может и облегчают жизнь автору этих конструкций, но могут приводить к обратному результату при использовании другими. Особенно если неправильное их использование не сопровождается никакими предупреждениями ни на этапе компиляции, ни этапе работы программы.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 14 2009, 10:49
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(SSerge @ Jun 14 2009, 13:21) *
Но, разумеется, хотелось бы собрать в одном месте все зависимости от номеров битов в портах, чтобы при правках не искать их по всей программе.

Описываю весь доступ к портам через макросы в одном h-файле и не парюсь.
В прочих файлах НИКАКОГО упоминания о портах, только макросы с осмысленными названиями. Просто для понимания. Существенно упрощает портирование.
К сожалению, есть проблема инлайнить функции, определенные в других модулях, теоретически можно тоже через #include, но это уж точно на изврат похоже.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 10:55
Сообщение #12


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Dog Pawlowa @ Jun 14 2009, 14:49) *
К сожалению, есть проблема инлайнить функции, определенные в других модулях, теоретически можно тоже через #include, но это уж точно на изврат похоже.


Это не изврат, а требование компилятора к видимости тела inline функции в том модуле, где вы хотите, чтобы эта функция была встроена. О чем многократно писалось на форуме.
Go to the top of the page
 
+Quote Post
KRS
сообщение Jun 14 2009, 10:59
Сообщение #13


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



На С++ можно с помощью перезагрузки операции присваивания. И потом объеденения полей в класс. Можно еще шаблоны прифигачить smile.gif

Только IMHO лучше, как тут уже писали, функции определить.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 14 2009, 11:07
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(sergeeff @ Jun 14 2009, 13:55) *
Это не изврат, а требование компилятора к видимости тела inline функции в том модуле, где вы хотите, чтобы эта функция была встроена. О чем многократно писалось на форуме.

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 11:16
Сообщение #15


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



А почему все макросы в одном h-файле можно поместить, а все inline функции в одном h-файле нельзя? Професиональные принципы не позволяют?
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 14 2009, 11:34
Сообщение #16


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Я бы сделал так:

#define UP(port, bit) port |= (1<<bit)
#define DOWN(port, bit) port &= ~(1<<bit)

Далее:

#define LIGHT P1OUT,1
#define MOTOR P2OUT,3
#define BEEPER P3OUT,2

Итого имеем:

UP(LIGHT);
DOWN(MOTOR);
UP(BEEPER);

Названия регистров взял от МСП, как наиболее актуального для меня

Если хочется именно структуры, то надо немного подумать.
Например, определить структуру Pin{}, в которой указать порт, номер пина и т.д. Например, забить туда все регистры порта (OUT,DIR,IE,SEL).
А потом уже эту структуру включать внутрь других структур.
Но всё равно без макросов не обойтись.
Либо класс рисовать.

Хотя, если взять тот же МСП, то там в io.h порты расписаны в том числе и как структуры, и можно написать
port1.out.pin3 = 1;
port2.out.pin1 = 0;
Тогда всё еще проще:
#define MOTOR port1.out.pin3;
...
MOTOR = 1;
C инициализацией других регистров порта опять же, нужно отдельно думать.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 14 2009, 11:35
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Dog Pawlowa @ Jun 14 2009, 14:49) *
К сожалению, есть проблема инлайнить функции, определенные в других модулях, теоретически можно тоже через #include, но это уж точно на изврат похоже.

Напрасно Вы так - вовсе не изврат, а очень полезный в некоторых случаях прием.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 14 2009, 17:09
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(aaarrr @ Jun 14 2009, 14:35) *
очень полезный в некоторых случаях прием.

ОК, я подумаю. Хотелось бы уточнить случаи.

Вопрос то в чем - если придерживаться какой-то структуры проекта, логичного разбиения проекта на модули (файлы), то достаточно сложные инлайновые функции должны быть определены в соответствующих модулях. И им нечего быть включенными в другие модули. Как раз недавно пришлось воспользоваться инлайном и оптимизацией для быстрых операций в прерывании.

Если же функция вырождается в дерганье выводом или считывание его состояния, то объясните мне плз, в чем преимущество инлайновой функции по сравнению с простейшим макросом:
#define ON_BACKLIGHT (P1OUT|=P1_BACKLIGHT),
где #define P1_BACKLIGHT 0x02 //output


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 14 2009, 17:16
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Dog Pawlowa @ Jun 14 2009, 21:09) *
ОК, я подумаю. Хотелось бы уточнить случаи.


Например, есть у меня в модуле display такая функция:
Код
__forceinline void disp_set_dot_alpha(u_int x, u_int y, DISP_COLOR color, u_char alpha)
{
    u_int c0, c1, mask;
    
    if(alpha > 0)
    {
        c0 = color;
        if(alpha < DISP_MAX_ALPHA)
        {
            c1 = *((u_short*)&disp_frame + (y * DISP_WIDTH) + x);
            mask = 0x07e0f81f;
            c0 = (c0 | (c0 << 16)) & mask;
            c1 = (c1 | (c1 << 16)) & mask;
            c0 = ((c0 * alpha) >> 5) & mask;
            c1 = ((c1 * (DISP_MAX_ALPHA - alpha)) >> 5) & mask;
            c0 = c0 + c1;
            c0 |= c0 >> 16;
        }
        *((u_short*)&disp_frame + (y * DISP_WIDTH) + x) = c0;
    }
}


Тащить всю работу с графикой в один модуль неразумно, до макроса не вырождается, зато как инлайн функция существенно повышает производительность.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 17:29
Сообщение #20


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Dog Pawlowa @ Jun 14 2009, 20:09) *
#define ON_BACKLIGHT (P1OUT|=P1_BACKLIGHT),
где #define P1_BACKLIGHT 0x02 //output


Это значит, что где-то кто-то может встретить в вашей программе:
Код
...
ON_BACKLIGHT;
...


Вы сами-то как оцениваете читабельность такого выражения?
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 14 2009, 17:36
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(aaarrr @ Jun 14 2009, 20:16) *
зато как инлайн функция существенно повышает производительность.

ОК, спасибо. Видимо, не сталкивался.
Но в таком виде функция не инклюдится, или я не знаю эту среду/компилятор?

Цитата(sergeeff @ Jun 14 2009, 20:29) *
Вы сами-то как оцениваете читабельность такого выражения?

Супер! Превосходная ! Ни у кого такого нет! smile.gif
"Включить подсвет", насколько мне известно...
Большие буквы, отсутствие скобок -> значит это макрос для работы с портами -> см файл project_ports.h
Лет пят-шесть так работаю, маразм наступает, но вот с этим пока проблем не было.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 14 2009, 17:41
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Dog Pawlowa @ Jun 14 2009, 21:30) *
Но в таком виде функция не инклюдится, или я не знаю эту среду/компилятор?

Вы имеете в виду __forceinline? Это от RVCT.

Цитата(Dog Pawlowa @ Jun 14 2009, 21:36) *
Супер! Превосходная ! Ни у кого такого нет! smile.gif

Ну не знаю, не могу разделить Ваши восторги. Понятно, что при помощи макросов можно заставить 'C' выглядеть как что-то совсем другое, но, ИМХО, лучше так не делать.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 17:48
Сообщение #23


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Dog Pawlowa @ Jun 14 2009, 20:36) *
Супер! Превосходная ! Ни у кого такого нет! smile.gif

Ну это, условный рефлекс, наверное.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 14 2009, 17:55
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(aaarrr @ Jun 14 2009, 20:41) *
Вы имеете в виду __forceinline? Это от RVCT.

Нет, я не только это я имею ввиду. Как тут отмечалось, чтобы функция инлайнилась, нужно, чтобы ее текст попадал в область видимости, то есть ее текст должен быть перенесен в модуль, где она используется, как то так:
#define DISPL_SET_DOT_ALPHA __forceinline void disp_set_dot_alpha(u_int x, u_int y, DISP_COLOR color, u_char alpha) \
{ \
u_int c0, c1, mask; \
if(alpha > 0) \
{ \
...

Цитата(aaarrr @ Jun 14 2009, 20:41) *
Понятно, что при помощи макросов можно заставить 'C' выглядеть как что-то совсем другое, но, ИМХО, лучше так не делать.

Так сложилось в жизни, что был период turbo pascal 6.0/ Pascal Borland 7.0 for embedded applications, so I don't follow strong rules in C smile.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 14 2009, 17:59
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Dog Pawlowa @ Jun 14 2009, 21:55) *
как то так:
#define DISPL_SET_DOT_ALPHA __forceinline void disp_set_dot_alpha(u_int x, u_int y, DISP_COLOR color, u_char alpha) \
{ \
u_int c0, c1, mask; \
if(alpha > 0) \
{ \
...

Только не так, Боже упаси! Функция в header'е display.h, который и подключается.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 14 2009, 18:04
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(sergeeff @ Jun 14 2009, 20:48) *
Ну это, условный рефлекс, наверное.

Форум "электроникс" - 1) достаточно модерируемый и 2) самоорганизующийся форум.
Я удивлен тем фактом, что мне приходится отметать Ваш переход на какие-то посторонние от техники аспекты.
Или Вы так зашорены, что больше нечего сказать?

Цитата(aaarrr @ Jun 14 2009, 20:59) *
Только не так, Боже упаси! Функция в header'е display.h, который и подключается.

А, ну да, конечно...


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 18:41
Сообщение #27


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Dog Pawlowa @ Jun 14 2009, 21:04) *
Или Вы так зашорены, что больше нечего сказать?


1. При чем тут зашоренность. Абсолютное большинство программистов, увидев
Код
ABC()
сразу поймет, что вызывается некая функция, т.е. некая локальная обработка данных, а
Код
ABC;
может означать все что угодно. Может это чтение из глобальной переменной ABC в стиле уважаемого гуру zltigo, a может вызов макро.
2. Есть понятие "стиль программирования". Мне кажется, что "стильно" написанная программа это такая, которая легко читается и сопровождается, и не только автором.
Go to the top of the page
 
+Quote Post
another_one
сообщение Jun 14 2009, 18:41
Сообщение #28


Местный
***

Группа: Участник
Сообщений: 252
Регистрация: 2-03-08
Пользователь №: 35 557



Цитата(MrYuran @ Jun 14 2009, 15:34) *
Я бы сделал так:



Всем большое спасибо за помощь
Причина редактирования: Нарушение п.3.4 Правил форума.


--------------------
One Chip is All You Need
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 18:59
Сообщение #29


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(another_one @ Jun 14 2009, 21:41) *
Всем большое спасибо за помощь


Небольшой пример для иллюстрации "прелестей" макро.
Код
#define UP(port, bit) port |= (1<<bit)

где-то в программе напишем:
Код
UP(port,2) + 3;


Понятно, что такое можно написать после долгих праздников, но это может быть и результатом типичной ляпы типа "copy/paste".
Очевидно, что это ляпа, но препроцессор это преобразует в
Код
port |= (1<<2) + 3;

и компилятор не моргнув никакими error/warning откомпилирует. Очевидно, что это ляпа, но сколько времени вы будете ее искать?

Ежели UP оформить в виде inline функции
Код
inline void UP(char port, char bit) {port &= ~(1<<bit);}


компилятор тут же выдаст что-нибудь типа '+' : illegal operand of type 'void' с указанием номера строки (VS 2008).

Если не хочется себе жизнь облегчать, то это, конечно, дело каждого уважаемого участника форума.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 14 2009, 19:05
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(sergeeff @ Jun 14 2009, 22:59) *
Ежели UP оформить в виде inline функции
Код
inline void UP(char port, char bit) {port &= ~(1<<bit);}

Ну, с тем же успехом можно сделать и в виде дефайна:
Код
#define UP(port, bit) {port &= ~(1<<bit);}
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 14 2009, 19:13
Сообщение #31


Гуру
******

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



Цитата(Dog Pawlowa @ Jun 14 2009, 20:36) *
Большие буквы, отсутствие скобок -> значит это макрос для работы с портами -> см файл project_ports.h

Отсутствующте скобочки они, конечно явно заставляют задуматься а что это такое? Причем задуматься без всякой на то надобности sad.gif.
Для подчеркивания того, что это макрос достаточным является запись большими буквами (хотя для "функций" я этим практически не пользуюсь - никакой информации это собственно не несет) естественным для 'C' является
on_backlight();
Ну или ксли хочется обратить внимание (обычно совсем без надобности) что это псевдофункция:
ON_BACKLIGHT();
Но и это излишество в вашем случае. Хотя иногда, явно полезно, например если что-то написано в незамысловатом стиле
Код
#define DEBUG_PRINT(  mask ) if( cfg_debug & (mask) )

DEBUG_PRINT( DL_RAW|DL_FULL )
    println( "Hello!" );



Цитата(aaarrr @ Jun 14 2009, 22:05) *
Ну, с тем же успехом можно сделать и в виде дефайна:
Код
#define UP(port, bit) {port &= ~(1<<bit);}

Точнее так smile.gif:
Код
#define up(port, bit) {(port) &= ~(1<<(bit));}


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 14 2009, 19:14
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Да-да, copy-paste, в первый раз и "char" забыл убрать smile.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 14 2009, 19:16
Сообщение #33


Гуру
******

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



Цитата(sergeeff @ Jun 14 2009, 21:59) *
Небольшой пример для иллюстрации "прелестей" макро.

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 14 2009, 19:38
Сообщение #34


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(zltigo @ Jun 14 2009, 22:16) *
Просто макросы, как, впрочем и программы, надо уметь писать. Причем умение писать макросы не бог весть какое великое.


Согласитесь уважаемый гуру, что написать "дуракоустойчивый" макрос сложнее (хотя бы с точки зрения отладки) эквивалентной inline функции.

Во-вторых, я ведь просто для примера привел первый пришедший на ум пример когда макро, не мной написанное, а приведенное коллегами как пример для подражания, абсолютно молча привело к генерации неправильного С-ного кода.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 14 2009, 19:54
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(sergeeff @ Jun 14 2009, 22:38) *
... написать "дуракоустойчивый" макрос сложнее ...

Я то опираюсь на свою статистику - она более чем удовлетворительная.
И вообще, существуют правила, вроде бы очевидные и понятные, например правила проверки равенства (константа на первом месте), затрудняющие чтение программы (по крайней мере лично у меня).
Ну а скобочки ... говорю - из Паскаля я. Меня не заставляют задуматься. Те, кто использует мои тексты - тоже вроде не жалуются.
Хотя сомнение зародили, если такая точка зрения есть, ничего не стоит попробовать.

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 14 2009, 20:05
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Dog Pawlowa @ Jun 14 2009, 23:54) *
Кстати, указание inline, насколько я помню, не является безусловным и обязательным для компилятора, или?

Не является. Но, во-первых, есть прагмы/модификаторы, настоятельно рекомендующие это компилятору (типа упомянутого __forceinline для RV); во-вторых, вредительством и саботажем компилятор тоже заниматься не станет.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 14 2009, 20:11
Сообщение #37


Гуру
******

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



Цитата(sergeeff @ Jun 14 2009, 22:38) *
Согласитесь уважаемый гуру, что написать "дуракоустойчивый" макрос сложнее (хотя бы с точки зрения отладки) эквивалентной inline
функции.

Ну не знаю, не знаю... Сложность очень отностительная, при этом для написания функций тоже надо немного думать и знать механихм заинлайнивания, индивиуальные для компилятора правила требовния (на самом деле просьбы smile.gif )принудительного заинлайтивания, принудительное откючение inline при отключении оптимизации что тоже может привести к проблемам (ногомахание по времени вдруг посыпалось, стек в начал больше использоваться). Кроме того макросы могут быть и много более мощными и читаемыми - у меня нередко встречаются макросы просто и естественно работаюшие, напимер, с десятком разных параметров, да, такой макрос не совсем прост, но и inline (точнее любая) функция более, чем уродлива в таких случаях.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jun 14 2009, 20:46
Сообщение #38


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(sergeeff @ Jun 14 2009, 21:41) *
2. Есть понятие "стиль программирования". Мне кажется, что "стильно" написанная программа это такая, которая легко читается и сопровождается, и не только автором.
В общем согласен. Но только с оговорокой "легко читается и сопровождается людьми, имеющими определённый уровень подготовки". Ни в коем случае не всеми, кто написал "Hello, world!".
А то ведь и в "человеческих" языках есть всякие там сложноподчинённые предложения, идиомы с прочими тропами, не говорю уже о профессиональной терминологии - тоже ведь не всё сказанное всем понятно будет, причём не только тем, кто только начал язык осваивать, но и многим "носителям". И это нормально.
Я немного увожу в сторону от основной темы обсуждения, но когда начинается "указательную арифметику не использовать, плохо читается" и т.п. я думаю - может просто надо уровень читателей поднимать?
Ведь в "должно быть понятно" можно докатиться до уровня рекламы стирального порошка или там "ретоны".
Когда вижу как бы на С написанное
Код
  if( flag )
  {
    struct.member[index] = a;
  }
  else
  {
    struct.member[index] = b;
  }
вместо
Код
   struct.member[index] = flag ? a : b;
я просто поражаюсь - насколько надо не любить и не знать С, чтобы так писать. А если это политика "чтобы понятно было", то на кого рассчитывается? И сможет ли этот "кто" понять всю программу?

Да, с маленькими детьми обычно разговаривают очень упрощённым языком (хотя и тут встречал мнение, что чрезмерное упрощение вредит развитию), но если так разговаривать со школьником...
Да, школьнику какую-то не сильно сложную медицинскую/физическую/... проблему можно и нужно уметь объяснить в каких-то базовых понятиях, но если профессионалы между собой начнут исключительно так общаться... Это им будет только мешать, затруднять общение. Конечно, если залезть в "башню из слоновой кости", то можно себя чувствовать крутым профи только потому, что тебя никто не понимает, это другая крайность.

Оптимум где-то посредине, и, на мой взгляд, в случае с С в этот оптимум входит понимание возможностей и ограничений макросов, а не вера в то, что они вредны, почёрпнутая из агитации за С++, причём на примерах ошибок, которые более менее грамотный программист просто не должен уже совершать (а на уровне, на котором они совершаются, и на С++ ничего хорошего не будет написано). Уровень их использования, который обсуждается в этой теме, не должен приводить к каким-то ощутимым на фоне всей программы задержкам понимания текста. Любой знающий язык С, а не некое усечённое подмножество "разрешённое к применению в фирме" должен быстро с ним разобраться.
Это понимание требует какого-то своего опыта. Начинающим сразу с С++ и не собирающимся работать на С может и можно послабление дать. Но с учётом того, что они (теоретически) должны научиться понимать гораздо более сложные вещи - макросы такого уровня они должны понимать легко.

Также в этот оптимум входит достаточное понимание указателей, чтобы не сильно долго задерживаться на строке
Код
a = (flag ? sin : cos)(fi);

Duff's device в него, пожалуй, не включу (хотя для понимания сути switch это весьма полезный пример и он есть в упражнениях у Страуструпа в "Язык программирования С++", причём это упражнение с низким уровнем сложности).


Цитата(sergeeff @ Jun 14 2009, 21:59) *
Небольшой пример для иллюстрации "прелестей" макро.
Код
#define UP(port, bit) port |= (1<<bit)

где-то в программе напишем:
Код
UP(port,2) + 3;
Можно и без макросов и без указателей и без goto наворотить такое, что никто не разберёт и не сможет сопровождать. Точно так же, как и имея словарный запас в три сотни слов можно нести околесицу. Приведенный Вами пример настолько "букварный", что или он из букваря и взят, или написавшему этот код человеку надо наконец-то вдумчиво прочесть книжку по языку С.

Вы никогда не видели примеры "индусского" кода на java, где "корень всех зол" в виде макросов отсутствует?

Что бы Вы сказали, если бы кто-то привёл пример такого кода как доказательство того, что с java надо уходить на С ?

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

Цитата(sergeeff @ Jun 14 2009, 21:59) *
Ежели UP оформить в виде inline функции
Код
inline void UP(char port, char bit) {port &= ~(1<<bit);}
То на попытку применить эту функцию к порту будет выдано сообщение об ошибке. А так - она вообще ничего полезного не делает, так как модифицирует свой аргумент типа char.


Да, для avr-gcc можно написать
Код
// для С99 так
static inline void UP( volatile uint8_t *port, uint8_t bit)
{
    *port |= 1 << bit;
}

// а для режима С++ ещё и так
static inline void UP2( volatile uint8_t& port, uint8_t bit)
{
    port |= 1 << bit;
}
Но
1) для IAR это уже не прокатит, там по-другому описаны порты, типы volatile uint8_t * и volatile uint8_t & не подойдут.
А вот правильно написанный макрос UP будет работать и там, и там.
2) а с первого раза и inline-функцию не вышло написать правильно wink.gif За что боролись?

Ага. Вроде бы это должно работать где угодно.
Код
template<typename PP> inline void
UP3( PP & port, uint8_t bit)
{
    port |= 1 << bit;
}
Но это уже совсем не С, так что может иметь отношение только к разговору о (не)применении макросов в С++, даже к C99 отношения не имеет, а, как тут в параллельной теме выяснилось, и С99 иногда непозволительная роскошь.

Постаравшись, можно залудить и что-то соответствующее по функционалу "макросам имени Аскольда Волкова" (тут упоминались несколько раз и приводились версии разного уровня развития идеи, но с лёту нашёл только одно сообщение), но не вижу смысла. У меня в связи с макросами ни аллергии, из-за "перееда" в детстве, ни полной беспомощности нетренированной имунной системы из-за жизни в стерильной среде нет.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 14 2009, 20:52
Сообщение #39


кекс
******

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



Меня как-то никогда не смущало написать пару десятков inline функций с осмысленными названиями, чтобы абстрагироваться от портов полностью.

Код
static inline void hal_SetRTS0(void)
{
    PORTG |= (1 << RTS0);
}

static inline void hal_ClrRTS0(void)
{
    PORTG &= ~(1 << RTS0);
}

static inline void hal_SetDTR0(void)
{
    PORTG |= (1 << DTR0);
}

static inline void hal_ClrDTR0(void)
{
    PORTG &= ~(1 << DTR0);
}


static inline void hal_PutRTS0(U8 val)
{
    if (val)
        hal_SetRTS();
    else
        hal_ClrRTS();
}

static inline void hal_PutDTR0(U8 val)
{
    if (val)
        hal_SetDTR();
    else
        hal_ClrDTR();
}


static inline U8 hal_GetCTS0(void)
{
    return (PINE & (1 << CTS0)) != 0;
}

static inline U8 hal_GetDCD0(void)
{
    return (PINB & (1 << DCD0)) != 0;
}

static inline U8 hal_GetDSR0(void)
{
    return (PINB & (1 << DSR0)) != 0;
}

static inline U8 hal_GetRI0(void)
{
    return (PINB & (1 << RI0)) != 0;
}
....


А уже потом где надо, эти функции с осмысленными названиями назначать структурам:

Код
typedef struct tagFLOW_CONTROL
{
    U8 enabled;   // flow control enabled (check CTS before transmitting)

    // acquiring signals cbs
    void (*On_DCD_Up)(struct tagFLOW_CONTROL *pCtrl);
    void (*On_CTS_Up)(struct tagFLOW_CONTROL *pCtrl);
    void (*On_DSR_Up)(struct tagFLOW_CONTROL *pCtrl);
    void (*On_RI_Up)(struct tagFLOW_CONTROL *pCtrl);

    // losing signals cbs
    void (*On_DCD_Down)(struct tagFLOW_CONTROL *pCtrl);
    void (*On_CTS_Down)(struct tagFLOW_CONTROL *pCtrl);
    void (*On_DSR_Down)(struct tagFLOW_CONTROL *pCtrl);
    void (*On_RI_Down)(struct tagFLOW_CONTROL *pCtrl);
    
    void (*set_rts_cb)(U8 val);
    void (*set_dtr_cb)(U8 val);
    
    U8   (*get_cts_cb)(void);
    U8   (*get_dsr_cb)(void);
    U8   (*get_dcd_cb)(void);
    U8   (*get_ri_cb)(void);
} TFLOW_CONTROL, *PFLOW_CONTROL;

...

#if (UART1_FULL_RS232)
    uart_con.u1_rs232_control.set_dtr_cb = hal_PutDTR0;
    uart_con.u1_rs232_control.set_rts_cb = hal_PutRTS0;
    uart_con.u1_rs232_control.get_cts_cb = hal_GetCTS0;
    uart_con.u1_rs232_control.get_dsr_cb = hal_GetDSR0;
    uart_con.u1_rs232_control.get_dcd_cb = hal_GetDCD0;
    uart_con.u1_rs232_control.get_ri_cb  = hal_GetRI0;

    uart_con.u1.pCtrl = &uart_con.u1_rs232_control;
    Kernel_SetTask( u1_DispatchRemoteFlowCtrlEvents, 5, TASK_PERIODIC);
#endif


Зачем нужны всякие макросы и прочая фигня для работы с портами то?
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jun 14 2009, 20:58
Сообщение #40


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



====================
Кстати, об исходной теме и проблемах её автора :-)

В этой теме может что-то полезное найдётся.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 14 2009, 21:03
Сообщение #41


Гуру
******

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



Цитата(defunct @ Jun 14 2009, 23:52) *
Зачем нужны всякие макросы и прочая фигня для работы с портами то?

Зачем нужна вся эта фигня для работы с портами то?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 14 2009, 21:07
Сообщение #42


кекс
******

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



Цитата(zltigo @ Jun 15 2009, 00:03) *
Зачем нужна вся эта фигня для работы с портами то?

Как правило __работать__ с портами не нужно.
Нужно работать с какими-то внешними объектами, так уж получается что через порты. Порты - промежуточное звено, о котором лучше всего забыть вообще.
Упоминания о портах у меня заканчиваются в hal и нигде более в программе не вспоминаются.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 14 2009, 21:16
Сообщение #43


Гуру
******

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



Цитата(defunct @ Jun 15 2009, 00:07) *
Нужно работать с какими-то внешними объектами, так уж получается что через порты. Порты - промежуточное звено, о котором лучше всего забыть вообще.

А вместо декларируемого HAL для "объекта" получена просто заумная работа с отдельными битам sad.gif. Вы не одиноки sad.gif, а заумные HAL пишут с неменьшим "успехом" и на макросах. Уму не растяжимой "красоты" пример HAL можно глянуть в SimpliciTI от TI. Ну их еще можно понять - а нефиг читать и портировать - берите и пользуйте только с нашими продуктами, как есть.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 14 2009, 21:28
Сообщение #44


кекс
******

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



Цитата(zltigo @ Jun 15 2009, 00:16) *
А вместо декларируемого HAL для "объекта" получена просто заумная работа с отдельными битам sad.gif.

HAL у меня не декларирует непосредственно объекты (объекты описываются уже в соответствующих им файлах).
HAL у меня отделяет программу от МК. (Двухступенчатый HAL получается). В примере выше, TFLOW_CONTROL описан не в HAL, а в uart.h, т.к. это объект связанный с UART'ом.

Если мне нужно включить реле1 то я предпочту написать

hal_RelayOn();

если зажечь зеленый светодиод, а не красный и не желтый.

hal_GreenLedOn();

вместо

SET_BIT( PORT_HZx, PIN_HZx);
CLR_BIT( PORT_HZy, PIN_HZy);

или других извратов.


В свою очередь, это дает возможность, легко управлять временем.
Например отключить реле __через 2 секунды__ после включения, я могу сразу же при включении реле:

hal_RelayOn();
Kernel_SetCb( hal_RelayOff, 2000, SEMA_NULL);

Ну и полностью забыть о GPIO портах как о классе, вне HAL.

Цитата
Вы не одиноки , а заумные HAL пишут с неменьшим "успехом" и на макросах.

на макросах такая конструкция
hal_RelayOn();
Kernel_SetCb( hal_RelayOff, 2000, SEMA_NULL);
непрокатит.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 14 2009, 21:39
Сообщение #45


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Jun 15 2009, 01:28) *
на макросах такая конструкция
hal_RelayOn()
Kernel_SetCb( hal_RelayOff, 2000, SEMA_NULL);
непрокатит.
а почему не прокатит-то ?
почему макрос "Kernel_SetCb" не сможет укладывать countdown значение 2000 в соответствующую ячейку массива ?
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 14 2009, 21:46
Сообщение #46


кекс
******

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



Цитата(singlskv @ Jun 15 2009, 00:39) *
а почему не прокатит-то ?
почему макрос "Kernel_SetCb" не сможет укладывать countdown значение 2000 в соответствующую ячейку массива ?

Потому что Kernel_SetCb делает то что написано в названии - одноразово вызывает заданную функцию по таймауту или по событию в зависимости от того, что произойдет раньше.
Если вместо функции первым параметром дадите макрос (CLR/SET_PIN_X), думаю очевидно, что программа даже нескомпилится, т.к. у макроса не может быть адреса.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 14 2009, 21:54
Сообщение #47


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Jun 15 2009, 01:46) *
Потому что Kernel_SetCb делает то что написано в названии - одноразово вызывает заданную функцию по таймауту или по событию в зависимости от того, что произойдет раньше.
Если вместо функции первым параметром дадите макрос (CLR/SET_PIN_X), думаю очевидно, что программа даже нескомпилится, т.к. у макроса не может быть адреса.
простите, а кто Вас заставляет давать в качестве параметра именно функцию, почему не передавать просто идентификатор пина ?
ну а если уж нужна разная обработка для разных пинов то можно и ссылку передавать и маску пина.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 14 2009, 22:00
Сообщение #48


Гуру
******

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



Цитата(defunct @ Jun 15 2009, 00:28) *
если зажечь зеленый светодиод, а не красный и не желтый.

hal_GreenLedOn();

вместо

SET_BIT( PORT_HZx, PIN_HZx);
CLR_BIT( PORT_HZy, PIN_HZy);

Ровным счетом никаких отличий sad.gif Вы написали "десяток функций" для дергания пином с разными именами, кто-то напишет десяток макросов с разными именами, кто-то опишет десяток дефайнов для макросов а-ля Волков.. На самом деле из всех этих вариантов самый правильный скорее всего будет тот, кто банально содержит минимум разных букв. Зачастую меня более всего устраивает и такое самое простое и незатейливое:
Код
#define P0B_SPI0_FSEL0    BIT22
#define P0B_SPI0_FSEL1    BIT31
#define IOSET_SPI0 IO0SET
#define SPI0_SEL_MASK    (P0B_SPI0_FSEL1|P0B_SPI0_FSEL0)
....
IOSET_SPI0 = SPI0_SEL_MASK;


И даже для тех-же светодиодов уровень абстакции может, и я считаю- должен, быть заметно выше, нежели ON/OFF
void led_mode( Led_e led, Led_mode_e mode );
led_mode( LED_RED, LM_FLASH_1 );
Задается какой светодиод и десяток режимов миганий. Несклько десятков строк в отдельном файле посященном светодиодам. В файле без всяких слишком многоэтажных наворотов пишется, все , что нужно. Такой HAL, я понимаю.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 14 2009, 22:13
Сообщение #49


кекс
******

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



Цитата(singlskv @ Jun 15 2009, 00:54) *
простите, а кто Вас заставляет давать в качестве параметра именно функцию, почему не передавать просто идентификатор пина ?
ну а если уж нужна разная обработка для разных пинов то можно и ссылку передавать и маску пина.

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

Kernel у меня работает с функциями и с задачами а не с идентификаторами пинов.
Любое __действие__ в общем виде всегда можно описать функцией. Номером пина либо еще какой-то фигней, любое действие не опишешь.

Точно также как в примере с реле я работаю и с более сложными процессами:

modem_Dial();
Kernel_SetCb( modem_Dial, 60000, SEMA_NULL); // повторный дозвон через минуту если не удалось дозвониться.

Цитата(zltigo @ Jun 15 2009, 01:00) *
Ровным счетом никаких отличий sad.gif

Ну как же никаких...
Вы можете поставить макрос в очередь задачь?
А инлайн функцию - запросто, компилер поймет что от него хотят. Там где можно заинлайнит, там где нужно вызовет по адресу.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 14 2009, 22:14
Сообщение #50


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Jun 15 2009, 02:03) *
Вы читали о чем я пишу? Я пишу что надо забыть о портах, номерах пинов, и т.п. чтобы спалось спокойно.
Наверное пока не уловил, поэтому и переспрашиваю... smile.gif
Цитата
Kernel у меня работает с функциями и с задачами а не с идентификаторами пинов.
А может Вашему кернелу уже работать с объектами а не с отдельными сущностями ?
Цитата
Точно также как в примере с реле я работаю и с более сложными процессами:
modem_Dial();
Kernel_SetCb( modem_Dial, 60000, SEMA_NULL); // повторный дозвон через минуту если не удалось дозвониться.
совсем не уловил почему countdown счетчик для пина должен принципиально отличаться от таково же для модема ?
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 14 2009, 22:25
Сообщение #51


кекс
******

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



Цитата(zltigo @ Jun 15 2009, 01:00) *
Зачастую меня более всего устраивает и такое самое простое и незатейливое:
Код
#define P0B_SPI0_FSEL0    BIT22
#define P0B_SPI0_FSEL1    BIT31
#define IOSET_SPI0 IO0SET
#define SPI0_SEL_MASK    (P0B_SPI0_FSEL1|P0B_SPI0_FSEL0)
....
IOSET_SPI0 = SPI0_SEL_MASK;


А если проц поменялся? У меня это просто:
hal_SPI0_Prepare();


Цитата(singlskv @ Jun 15 2009, 01:14) *
А может Вашему кернелу уже работать с объектами а не с отдельными сущностями ?

Вы о чем? Какие отдельные сущности?
Kernel работает с ___функциями____ которые описывают ___любые___ действия любых объектов.

Цитата
совсем не уловил почему countdown счетчик для пина должен принципиально отличаться от таково же для модема ?

Блин... дак ничем он и не отличается. smile.gif
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 14 2009, 22:30
Сообщение #52


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Jun 15 2009, 02:25) *
Блин... дак ничем он и не отличается. smile.gif
Ну а если ничем не отличается, то легко реализуем с помощью макросов...
и очень даже эфективненько...

Ну положите в конце концов адрес функции обработчика при инициализации...
зачем его каждый раз передавать ?
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 14 2009, 22:37
Сообщение #53


кекс
******

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



Цитата(singlskv @ Jun 15 2009, 01:30) *
Ну а если ничем не отличается, то легко реализуем с помощью макросов...
и очень даже эфективненько...

Что реализуемо с помощью макросов? Изобразите свой полет мысли, а то получается разговор слепого с глухим.

Цитата
Ну положите в конце концов адрес функции обработчика при инициализации...

куда положить?

Цитата
зачем его каждый раз передавать ?

Чтобы можно было зарегистрировать сколько угодно и каких угодно колбеков вестимо, с разными таймаутами и разными условиями запуска.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 15 2009, 05:37
Сообщение #54


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(defunct @ Jun 15 2009, 01:13) *
Вы можете поставить макрос в очередь задачь?
А инлайн функцию - запросто, компилер поймет что от него хотят. Там где можно заинлайнит, там где нужно вызовет по адресу.


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

Если предусматривается какая-то более сложная логика, то это не совсем порт, а, скажем объект какой-то типа звукового сигнала со своими параметрами, или моргающего светодиода, как в примере zltigo. Для обслуживания такого "объекта" прописывается свой сервис в каком-нить бэкграунде. Его параметры устанавливаются типа так:
void Beep (unsigned int ms, char beeps_qty), после чего "приложение" забывает о существовании этого объекта. Типичная организация системы без ОС.

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 15 2009, 06:31
Сообщение #55


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(ReAl @ Jun 14 2009, 23:46) *
где "корень всех зол" в виде макросов отсутствует?


1. Я нигде не утверждал, что макрос - страшное, ужасное зло. Бывают случаи, когда только они и работают.
2. "Букварный пример" он на то и пример, чтобы просто показать "подводные камни" макропрограммирования.
3. Все очень быстро в пылу дисскуссии забывают изначальный вопрос автора топика.
4. Любую программу можно написать десятком разных способов. Не спроста Кнут назвал свои книги "Искусство программирования".
5. Примеры с разложенными по строкам if .. else и тернарный оператор ? в 99% случае компилятором генерируются в одинаковый машинный код. Тут, как говорится, на вкус и цвет...
6. В большинстве случаев (есть и исключения) книги по программированию написаны людьми лично принимавшими участие в больших и огромных проектах и не знакомиться с их практическим опытом просто не разумно.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 15 2009, 06:44
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(sergeeff @ Jun 15 2009, 09:31) *
книги по программированию написаны людьми лично принимавшими участие в больших и огромных проектах и не знакомиться с их практическим опытом просто не разумно.

Неубедительно. Я то никогда не буду принимать участие в огромном проекте smile.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 15 2009, 06:46
Сообщение #57


кекс
******

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



Цитата(Dog Pawlowa @ Jun 15 2009, 08:37) *
В Вашем варианте смешаны в кучу и быстрые действия и медленные, в результате быстрые могут оказаться не такими быстрыми, как иногда требуется.

Если нужно совсем быстро опишу эти быстрые действия в том же HAL как еще одну inline функцию.. делов то..
Вы просто м.б. не представляете насколько это здорово, когда не только программа портируется без изменений с одного проца на другой, но и драйверы периферии портируются тоже практически без изменений (либо с очень небольшим числом таковых).

Цитата
Если предусматривается какая-то более сложная логика, то это не совсем порт,

А кому нужен совсем "порт" в чистом виде то? (ну кроме студентов которые проходят лабораторки по портам).
Надо выполнить действие. выполнить быстро. Тут inline функция работает ничуть не медленнее макроса, плюс к этому качеству она обладает еще и свойством обычной функции, и является частью стандарта языка.

А что такое макрос?

не подумайте что у меня есть какие-то предубеждения к макросам, я их тоже пользую ;> но не для портов, а например так:

Код
/***************************************
* Read access to RTL reg page          *
* ---> Addr 0x00..0x10 (including DMA) *
* <--- returns register value          *
***************************************/
#define nic_ReadReg( addr )\
  (*(V8 *)(NIC_BASE + (addr)))
  

/***************************************
* Write access to RTL reg page         *
* ---> Addr 0x00..0x10 (including DMA) *
* ---> value, data to be stored        *
* <--- returns: nothing                *
***************************************/
#define nic_WriteReg(addr, val)\
  (*(V8 *)(NIC_BASE + (addr)) = (val))


Когда точно уверен, что мне никогда не понадобится свойство функции от этого действия.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 15 2009, 07:05
Сообщение #58


Гуру
******

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



Цитата(defunct @ Jun 15 2009, 01:25) *
А если проц поменялся? У меня это просто:
hal_SPI0_Prepare();

Ничего не мешает и подниматься на более высокие уровни абстракции HAL - пример со сведодиодом я лично приводил. В этом случае задача абстрагироваться от смены прцессора не ставилась, причина более чем проста - SPI все несколько разные и нагрузка у меня на них большая,посему совсем не хочется все SPI стричь под одну гребенку, дабы все выглядели в угоду HAL одинаково. Причем, как правило, равняясь по слабейшему, они будут выглядеть одинаково уродливо sad.gif. Даже на более высоком уровне абстракции "драйвер" не всегда несколько контроллеров хорошо стригутся под одну гребенку. Много чего обычно приходится придумвать для эффективной работы не вообще, например, "SPI" (про разные MAC, CAN,... вообще молчу) а "конкретного SPI" и на фоне этих работ, меня, честно говоря, совсем не волнуют "пролемы" HAL для одинокого пина sad.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 15 2009, 07:11
Сообщение #59


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Dog Pawlowa @ Jun 15 2009, 09:44) *
Неубедительно. Я то никогда не буду принимать участие в огромном проекте smile.gif


1. Как говорится "Умные учатся на чужих ошибках..."
2. Никогда не говори никогда.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jun 15 2009, 08:03
Сообщение #60


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(sergeeff @ Jun 15 2009, 09:31) *
2. "Букварный пример" он на то и пример, чтобы просто показать "подводные камни" макропрограммирования.
Не спорю. Но с тем же успехом можно Вашу inline-функцию, просто модифицирующую свой собственный аргумент (независимо от того, как в данной системе представлены порты) использовать как пример "подводного камня" при использовании функций. Cобственно, что-то похожее и показывают в разговорах о передаче по ссылке и по значению. Ошибки, на мой взгляд, одного уровня, нормальный человек их может сделать только в начале обучения либо поздно вечером в пылу спора wink.gif

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

Цитата(sergeeff @ Jun 15 2009, 09:31) *
5. Примеры с разложенными по строкам if .. else и тернарный оператор ? в 99% случае компилятором генерируются в одинаковый машинный код. Тут, как говорится, на вкус и цвет...
А я об эффективности кода и не говорил. Это иллюстрация к "упрощённый язык для объяснения школьнику" и "общение профессионалов".
Многострочный вариант читается так:
Цитата
если флаг установлен, то такому-то элементу такого-то массива такой-то структуры присвоить а
если же он сброшен, то такому-то элементу такого-то массива такой-то структуры присвоить b
а, одной и той же структуры!
а, одного и того же массива!
а, и индекс одинаковый!
щас... да, точно, всё до буковки одинаково.
значит так, такому-то элементу такого-то массива такой-то структуры в зависимости от флага присвоить a или b
тогда как тернарная операция сразу приводит понимание текста к последней строке. Конечно, только для человека, знающего язык достаточно хорошо.

Так значит тут - "на вкус и цвет", а макросы - снижают читаемость и сопровождаемость текста?


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jun 15 2009, 08:24
Сообщение #61


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Dog Pawlowa @ Jun 14 2009, 13:49) *
Описываю весь доступ к портам через макросы в одном h-файле и не парюсь.
В прочих файлах НИКАКОГО упоминания о портах, только макросы с осмысленными названиями. Просто для понимания. Существенно упрощает портирование.
К сожалению, есть проблема инлайнить функции, определенные в других модулях, теоретически можно тоже через #include, но это уж точно на изврат похоже.

Поступаю также. Один в один.
Как раз для переносимости очень удобно. Чётко знаешь что этот файл придётся переписать.
Никакой неразберихи в файлах проекта у меня не возникает, так как там уже используются "осмысленные" макросы. Типа LED_ON или RG_STB. Для одного проекта (проца) может быть LED_ON единицей, для другого нулём. Это не имеет значение. Так как правится макрос, и он по макросу LED_ON загорается. (Естественно я упрощаю). Можно былобы ожидать, что этот файл большим будет, но на самом деле - совсем пустяковый. Всё сведено в одно место, сразу видны все биты и порты, видна их инициализация. Короче очень удобно.

Если разработчик работает в коллективе, то должны быть определены какие то общие правила оформления проекта. Они должны постоянно корректироваться. Разработчики должны их придерживаться. Если груповой проект, то должен составляться план поекта и какие-то доп правила оформления (к типовым правилам).
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 15 2009, 08:33
Сообщение #62


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(ReAl @ Jun 15 2009, 11:03) *
Так значит тут - "на вкус и цвет", а макросы - снижают читаемость и сопровождаемость текста?


Макросы - это препроцессор, т.е. "до компилятора". Варианты if... и ? - компилятор. Вы лично часто изучаете листинг препроцессора? Уверен - почти никогда. Значит вы просто полагаетесь на то, что вы со своим многолетним опытом, ошибок при написании макросов не допускаете и препроцессор все сделал именно так, вы себе это представляете. А если ошибка есть, она трудноуловима (при одних данных есть, при других - нет, а еще хуже при одних типах данных - есть, при других - нет). Вам что больше по душе, чтобы компилятор вам хотя бы подсказывал про подобные потенциальные проблемы, или молча, по своему усмотрению чего-то там понаделал, а вы потом, "по вторичным половым признакам" аномального поведения программы это все вылавливали?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 15 2009, 10:43
Сообщение #63


Гуру
******

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



Цитата(SasaVitebsk @ Jun 15 2009, 11:24) *
Всё сведено в одно место, сразу видны все биты и порты, видна их инициализация....

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jun 17 2009, 08:57
Сообщение #64


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(zltigo @ Jun 15 2009, 13:43) *
...и взаимосвязь со взаимоисключениями. Причем, этот файл на самом деле и внутри сруктурирован - те-же биты, хоть и для светодиодов поименованы и соответсвенно ниже по файлу, т.е. уже уровнем выше smile.gif используются только эти имена. Все это хозяйство компактно, лаконично и достаточно легко изучается в том числе и глазами.

Именно так. Единственно, что я струкурирую по портам. Типа беру бит, обзываю его и объявляю макросы работы с ним с учётом специфики. Это даёт возможность не пропустить какой-либо бит. Так же комментирую этот бит если надо. С точки зрения программиста, часто схема просто не нужна. Точнее её он структурно представляет, а управление ей он читает именно в этом файле. При возвращении к проекту, чаще всего заглядываю именно в этот файл, для того чтобы вспомнить весь проект.
Кроме того с помощью условной компиляции, либо сменой данного файла, вы можете версию платы менять. Например в версии 1а сменили ноги при переразводке.
Go to the top of the page
 
+Quote Post

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

 


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


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