Easyelectronics.ru

Электроника для всех
Текущее время: 11 июл 2020, 04:12

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



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 140 ]  На страницу Пред.  1, 2, 3, 4, 5, 6
Автор Сообщение
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 28 окт 2018, 11:44 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1207
Mirmik писал(а):
Затрудняюсь сказать, почему нельзя просто обернуть блоком.

Просто с блоком можно получить, например, такой код:
Код:
if (...) {...};
else ...

Который не скомпилируется из-за ';'.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 28 окт 2018, 16:12 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 817
#define CONCAT(a,b) a##b - двойное сканирование, вроде как понятно.

#define dpr_2(X,Y) do{dpr_(X); soft_print(" "); dpr_(Y);}while(0) - бронирование условий, тоже понятно.

Декларация функции для автозаполнения - в примерах настойчиво упоминают printf(), смысла не уловил. Решение в лоб не работает.

#define COUNT_ARGS(...) ELEVENTH_ARGUMENT(_, ##__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
Подсчёт количества параметров. В макросе учитывается последний из общего количества, вся строка двигается в право - именно по этой причине обратный порядок цифр. Первый параметр убивает ожидание запятой, и двигает строку. А вот общее возможное количество аргументов 9-0 - осталось магией. В статье нет внятного объяснения. Однако если синхронно менять макросы COUNT_ARGS и ELEVENTH_ARGUMENT - то работать будет.
https://renenyffenegger.ch/notes/develo ... -arguments

Заметил у себя странность, или глюк.
Могу долго буксовать с поиском информации - трудность в составлении запроса на поиск. Однако чужое объяснение, возможно даже не совсем полное - позволяет взглянуть на проблему под другим углом.

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 28 окт 2018, 17:06 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
По идее конкатенация (_, ##__VA_ARGS__, ...) должна схлопывать запятую. Но у меня это почему-то не работает и COUNT_ARGS все равно выдаёт 1 на нольаргументов.

P.S. Ларчик просто открывался. Я компилировал с -std=c11, а чтобы эта фишка работала нужно компилировать в одном из gnu стандартов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 20 ноя 2018, 17:12 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 817
Ещё один вариант, более короткий и простой.
Встроенная GCC функция: int __builtin_types_compatible_p ( type1 , type2 ). Сравнивает два типа, 1 в случае совпадения.
https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
Код:
#define foo (x) \
  ({\
    typeof (x) tmp = (x); \
    if (__builtin_types_compatible_p (typeof (x), long double)) \
      tmp = foo_long_double (tmp); \
    else if (__builtin_types_compatible_p (typeof (x), double)) \
      tmp = foo_double (tmp); \
    else if (__builtin_types_compatible_p (typeof (x), float)) \
      tmp = foo_float (tmp); \
    else \
      abort (); \
    TMP; \
  })

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 20 ноя 2018, 20:19 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
Годно.

Могу отметить, что этот вариант непереносим в отличии от _Generic, потому что _Generic - это стандарт языка си, а __builtin_types_compatible_p - это расширение компилятора...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 21 ноя 2018, 04:39 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 817
Mirmik, есть идея сделать красиво, хотя и не в тему.
Простая вещь для arm
#define AND_PART(name_reg, value) (((value) << (name_reg ## _Pos )) & (name_reg ## _Msk))
Позволяет собирать содержимое регистров без многократной перезаписи как в LL. Например
Код:
    RCC->PLLSAICFGR = AND_PART (RCC_PLLSAICFGR_PLLSAIN, 252)    // PLLN frequency multiplication PLLSAI 50-432
                      |AND_PART (RCC_PLLSAICFGR_PLLSAIP, 8)     // P division factor for USB,RNG,SDMMC(48MHz) 2,4,6,8
                      |AND_PART (RCC_PLLSAICFGR_PLLSAIQ, 15)    // Q division factor for SAI clock  2-15
                      |AND_PART (RCC_PLLSAICFGR_PLLSAIR, 3);    // R division factor for LCD clock  2-7


Все определения имеют в своём составе разделитель "_", и меня посетила бешеная идея - разделить определения, и использовать как часть кода макроса. Для "##" я смог найти массу материала. Для разделения - только мелкие обрывки, например макрос offsetof (размер смещения) https://gcc.gnu.org/onlinedocs/gcc/Offs ... l#Offsetof .
Он в своём составе имеет "identifier", с точным указанием поиска ",". Только непонятно как оно работает.

Можно преобразовать определение в строку, найти первое и последнее "_", собрать обратно - с поиском и замены текста на выражение. Но это очень жирно. Думаю что должно быть более простое решение.

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 21 ноя 2018, 08:19 
Старожил

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 4198
Откуда: Чобля - долбаный кетайец
Только зачем писать лишние буквы? Чуваки, распространенное заблуждение, на котором попадаются многие. Макросы и дефайны придуманы не для того, чтобы запутать первоначальный смысл. А для того, чтобы убрать лишние повторения.
Вот пример удачного макроса:
Код:
/* макрос */
#define PRINT_TEXT(msg, line, xpos, color)               \
         len = strlen(msg);                        \
         GUI_PrintText_to_Layer(msg, len,             \
               xpos, (line) * LINE_STEP + LINE_YPOS,   \
               &infolayer_param, font2,            \
               ((color) | 0xF0), INFO_LAYER_DEFCOLOR);

/* применение макроса в тексте проги */
   /* Event */
   PRINT_TEXT(tbl_header_msg[0], 1, COL2_XPOS, HDR_COLOR)

   /* Coord */
   PRINT_TEXT(tbl_header_msg[1], 1, COL3_XPOS, HDR_COLOR)

   /* Pressure */
   PRINT_TEXT(tbl_header_msg[2], 1, COL4_XPOS, HDR_COLOR)

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 21 ноя 2018, 08:56 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 817
BusMaster писал(а):
Только зачем писать лишние буквы? Чуваки, распространенное заблуждение, на котором попадаются многие. Макросы и дефайны придуманы не для того, чтобы запутать первоначальный смысл. А для того, чтобы убрать лишние повторения.

Всё верно. Сначала cmsis, а потом ещё папка с драйверами на 22 мегабайта мелкого текста - тоже не хотели запутывать первоначальный смысл.

Нужно сделать макрос разделяющий A_B_C - до A, B, C, для последующих издевательств.
Например - RCC_PLLSAICFGR_PLLSAIN до (RCC, PLLSAICFGR, PLLSAIN).

Вот добавить символы к имени может любой дурак, а чтоб наоборот...

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 21 ноя 2018, 10:12 
Старожил

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 4198
Откуда: Чобля - долбаный кетайец
Да я совсем не о том. Вон те ваши RCC_PLLSAICFGR_PLLSAIN в тексте проги используются один раз и меняются один раз. Кстати, если вы раскроете макрос и посмотрите, сколько действий он делает, то (если вы думающий) подумаете - а нафига вы так написали, чего этим добились??
Я же вам привел макрос, который не хранится где-то в мегабайтах библиотек, он пишется под конкретный случай. Зато пользы от него - гораздо больше - я уже написал, какой именно пользы.

А то, что вы понаписали, более удобно записывается вот в таком виде:
где-то вверху файла:
Код:
/*---- PLL SAI ----*/
/* Rout =  in * PLLSAI_N / (PLLSAI_R * PLLSAI_RDIV)
* Qout = in * PLLSAI_N / (PLLSAI_Q * PLLSAI_QDIV) */
#define USE_PLLSAI
#define PLLSAI_N      192
#define PLLSAI_P      4      // выход на селектор 48 кГц USB, RNG
#define PLLSAI_Q      4
#define PLLSAI_R      6
#define PLLSAI_RDIV      4      // выход частоты LCD-TFT
#define PLLSAI_QDIV      2      // выход на селектор SAI1,2


дальше, по ходу текста в функции:
Код:
/*---- Конфигурация PLL SAI1 ----------------------------*/
#ifdef USE_PLLSAI
   RCC->PLLSAICFGR = (PLLSAI_N << 6) | (((PLLSAI_P >> 1) -1) << 16) |
                 (PLLSAI_Q << 24) | (PLLSAI_R << 28) ;
   RCC->DCKCFGR1 |= ((PLLSAI_RDIV / 4) << 16) |
                ((PLLSAI_QDIV - 1) << 8);

   RCC->CR |= RCC_CR_PLLSAION;

    /* Ожидание запуска PLL SAI */
   while((RCC->CR & RCC_CR_PLLSAIRDY) == 0)
   {  }
#endif /*USE_PLLSAI */
/*-------------------------------------------------------*/

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 21 ноя 2018, 10:49 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 817
BusMaster писал(а):
...и вам не надо лазить по тексту функции в середине файла, выискивая, где же вы там понаписали настройку частоты то...

Хорошая шутка. Настройку регистров нужно видеть там где оно физически записывается в регистры, а не через дополнительные переопределения. + защита от дурака, + защита от ошибок. _Pos и _Msk - это вообще-то основной файл проекта, если их там нет - значит сборка завершится ошибкой. А вам придётся ещё и в документацию заглядывать, искать те самые маски и смещения - что не исключает шанс ошибки.

BusMaster писал(а):
Вон те ваши RCC_PLLSAICFGR_PLLSAIN в тексте проги используются один раз и меняются один раз. Кстати, если вы раскроете макрос и посмотрите, сколько действий он делает, то (если вы думающий) подумаете - а нафига вы так написали, чего этим добились??

Конкретно RCC_PLLSAICFGR_PLLSAIN, а так-же 100500 похожих констант - вообще не меняются. Они либо есть, либо проект с ошибкой. А макрос один (пока) - работает как общее правило.
Напомнить что случается с константами в макросах?

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 21 ноя 2018, 13:29 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
Запятая в builtin_..... Ищется на уровне синтаксического анализатора к которому средствами языка мы подобраться не сможем. Так что нет. Искать символ _ как запятую не получится.

Не думаю, что есть достаточно простой способ решения этой задачи.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 21 ноя 2018, 15:04 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 817
Кхм, а текстовый массив из имени константы имеет наследие? Ну то-есть может обслуживаться препроцессором?, или это исключительно мышыный код?
Допустим у меня уже есть программный вариант, и он уже работает почти так как хочется (хотя и глючит). Смысла в нём мало, просто чтоб двигаться в перёд. В данный момент я споткнулся с переводом текстового массива в имя созвучное с константой. Пришлось сделать страшное - массив имён. И он отчего-то не хочет оптимизироваться в ноль. А других способов я не знаю.

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 21 ноя 2018, 17:52 
Старожил

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 4198
Откуда: Чобля - долбаный кетайец
Мда. Любите же вы придумывать себе сложности там, где их нет. Впрочем, если делать больше особо нечего, то можно и ковыряться потихоньку. Одно только жалко - не в прок.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 21 ноя 2018, 18:07 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
Не понял


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Слепая печать float/uint(8-32)_t/int(8-32)_t замена printf
СообщениеДобавлено: 21 ноя 2018, 18:20 
Старожил

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 4198
Откуда: Чобля - долбаный кетайец
Это не вам. Это - по поводу макросов.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 140 ]  На страницу Пред.  1, 2, 3, 4, 5, 6


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


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB