Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: HAL
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2, 3
AleksBak
Цитата(Сергей Борщ @ Apr 12 2016, 10:56) *
Заинтересовало. Глянул. Свежескачанные кубы для 4xx и 2xx. Версии от ноября прошлого года. Какая там многопоточность, о чем вы?

Код
#if (USE_RTOS == 1)
  /* Reserved for future use */
  #error " USE_RTOS should be 0 in the current HAL release "
#else
  #define __HAL_LOCK(__HANDLE__)                                           \


...

Оно все время не продекларировано это USE_RTOS и просто так. Пусть себе пишут (2 руками за) - 1. даренному коню в зубы не смотрят и 2. проверить/разобраться с Кубом что-то - самое то это (очень и очень многое с ним вообще-то можно проверить).
SasaVitebsk
2 AleksBak.
Да никто ни на индусов ни на HAL не нападает. Задача "создать универсальную библиотеку", в принципе не решаемая. Чем более универсальна она будет, тем она будет более громоздкая. Документация по ней превысит исходную документацию на кристалл в несколько раз. Вот и всё.
В результате, чтобы задействовать функцию, приходится смотреть в доки на библиотеку и доки на кристалл. Потом ещё рыться в библиотеках ну и так далее ... То есть при каком-то уровне абстракции это просто теряет смысл.
Ну, например, взять таймер. Хотим организовать ШИМ. Читаем 10 регистров и появляется примерно следующее
Код
  // Инициализация таймера ШИМ подсветки
  TIM_PWM_LIGHT->CR1 = TIM_CR1_CEN;            // Включить таймер
  TIM_PWM_LIGHT->CCMR2 = TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1;// PWM1
  TIM_PWM_LIGHT->CCER = TIM_CCER_CC4E;        // Включить канал CH4
  TIM_PWM_LIGHT->PSC = FPWM_PSC-1;            // Прескалер
  TIM_PWM_LIGHT->ARR = FPWM_MAX-1;            // Частота ШИМ 200 Гц

Ну и управление яркостью, соответственно
TIM_PWM_LIGHT->CCR4 = teklight;
...
Если захочешь написать это с помощью HAL, то меньше не окажется ... Читать меньше тоже не придётся ... Более того, это всё ещё будет завязано ещё на какую-нибудь библиотеку и... погнали наши городских. В результате подключено 10 библиотек HAL, для того, чтобы махнуть одной ножкой... Какие преимущества то?
Это всё уже писано 10 раз.
Против самих библиотек никто не возражает. Иногда удобно. Например туда посмотреть.
AleksBak
Цитата(SasaVitebsk @ Apr 12 2016, 12:00) *
...
Это всё уже писано 10 раз.
...

Полностью на 100.0% согласен. Так и стараюсь делать вообще-то. Спс за развернутый ответ. ТС хотел в этой теме какие если есть важные ошибки в HAL - чтобы про них кто-то написал и тогда не буду тему "захламлять". До этого "наводящий" вопрос о __HAL_LOCK/__HAL_UNLOCK я спецом задал, а то так бы тут и обсуждали перевод слова "hal" и т.п.
zltigo
QUOTE (SasaVitebsk @ Apr 12 2016, 11:00) *
Задача "создать универсальную библиотеку", в принципе не решаемая.

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

Obam
Цитата(zltigo @ Apr 12 2016, 13:37) *
…И уже пошли чипы и платформы на котрых нет того-же описания чипа в доступе как класс…


Китайцы, в основном, и континентальные и островные…
Tarbal
Цитата(zltigo @ Apr 12 2016, 13:37) *
Угу, только не заметили-ли Вы, что "универсальная библиотека" это еще цветочки и уже идет полным ходом создание "универсальной программы" sad.gif. Например, под наванием "линукс". И уже пошли чипы и платформы на котрых нет того-же описания чипа в доступе как класс - только зашитые "библиотеки", или вообще "линукс" и точка.


Да Бог с вами. Линукс это тысячи разных программ. Так не пользуйтесь теми платформами, что используют не open source.
SasaVitebsk
Цитата(zltigo @ Apr 12 2016, 12:37) *
Угу, только не заметили-ли Вы, что "универсальная библиотека" это еще цветочки и уже идет полным ходом создание "универсальной программы" sad.gif. Например, под наванием "линукс". И уже пошли чипы и платформы на котрых нет того-же описания чипа в доступе как класс - только зашитые "библиотеки", или вообще "линукс" и точка.

Да заметил. Но пока ещё далеко до завершения этой работы... Даже с идеалогией не всё в порядке.
И вообще. Посмотрите, почему линукс? Он так хорош? Да нет, просто объём работы (суммарный, а не только по ОС) таков, что реально сложно за него взяться.
Это ведь как в любом проекте. Когда его завершаешь, то видишь кучу мелочей, которые надо бы исправить. И беда в том, что на начальном этапе ты этих мелочей не заметил, или не предусмотрел механизмов которые помогают их красиво устранить. А на этапе, когда ты их видишь, к сожалению, их устранение приводит к коренной переработке всего проекта. А ты на это не готов. И количество людей, принимающих участие в проекте, не улучшает его свойств (не уменьшает количество огрехов), а, наоборот, увеличивает. И... поехало всё с нуля.
StdPeriph_Driver -> HAL_Driver ->
zltigo
QUOTE (Tarbal @ Apr 12 2016, 13:52) *
Да Бог с вами. Линукс это тысячи разных программ. Так не пользуйтесь теми платформами, что используют не open source.

Ну и что, что тысячи? В этом-то и проблема от которой никакой "open" не спасает - количество латанного перелатанного "open" кода уже просто превысило все мыслимые размеры. Никакакая опенутость НЕ делает работоспособным поминаемый здесь HAL. Все, что можно, это сделать еще одну заплатку, причем надо понимать, что всяких заплаток завтра еще наделают без Вас. После этого у Вас альернатива, либо остаться на текущей версии того-же HAL, либо постоянно разбираться с потоком заплаток и нововведений во всяких свежелатанных версиях HAL и их последствиями.
Для того, что-бы потушить костер достаточно в него подкинуть бревно побольше. Жупел "open" это именно такое бревно.

Массой НЕ "open" платформ уже просто не возможно не пользоваться, например, на какой платформе Ваш телефон?




QUOTE (SasaVitebsk @ Apr 12 2016, 14:11) *
И вообще. Посмотрите, почему линукс? Он так хорош?

Просто один из примеров - можно сказать флагман бизнесмодели "секс по телефону бесплатный - платите только за телефонный звонок", но конечно, не единственный.
QUOTE
И количество людей, принимающих участие в проекте, не улучшает его свойств (не уменьшает количество огрехов), а, наоборот, увеличивает. И... поехало всё с нуля.
StdPeriph_Driver -> HAL_Driver ->

Хуже того, в большинстве больших опенутых проектов набегают новички, которые даже уже основ НЕ смогли понять и радостно начинают ваять альтернативные яйца в профиль, но уже совсем через анус sad.gif.
x893
У меня такой подход - сначала кубом делается инициализация и настройка по максимуму.
Затем дебаггером прохожу и смотрю что всё действительно как задумывалось.
После этого выкидываю всё лишнее (вместе с кубовскими поделками).
Остается только то, что нужно (с коментариями из куба).
Из плюсов - не надо лазить по RM в поисках битов/регистров, более-менее понятные коментарии.
Ну и размер конечно.
zltigo
QUOTE (SasaVitebsk @ Apr 12 2016, 14:11) *
И беда в том, что на начальном этапе ты этих мелочей не заметил, или не предусмотрел механизмов которые помогают их красиво устранить. А на этапе, когда ты их видишь, к сожалению, их устранение приводит к коренной переработке всего проекта. А ты на это не готов.

Я инода все-же такое делаю. Помогает, что срок жизни изделий по железу очень большой (10 лет типично), вот и становится разумным переодически вдыхать новую жизнь в старое железо. При этом рефакторинг тоже делаю.
segment
Цитата(x893 @ Apr 12 2016, 14:31) *
Из плюсов - не надо лазить по RM в поисках битов/регистров, более-менее понятные коментарии.

Жесть.
zltigo
QUOTE (x893 @ Apr 12 2016, 14:31) *
У меня такой подход - сначала кубом делается инициализация и настройка по максимуму

Я во всякие вещи типа "библиотек" и "примеров" заглядываю только в одном случае, если что-то упорно не получается по документации сделать. Но помогает далеко не всегда, ибо не получается сразу обычно что-то более хитрое, чем два байта переслать.
В чем смысл делать "инициализация и настройка по максимуму" вообще не понимаю. Разбираться с железом надо по любому постепенно и только с тем, которое СЕЙЧАС нужно. Шаг за шагом - GPIO помигать светодиодом, UART - поднять консольку, таймер - операционку поднять,.....
Tarbal
Цитата(zltigo @ Apr 12 2016, 15:39) *
Я во всякие вещи типа "библиотек" и "примеров" заглядываю только в одном случае, если что-то упорно не получается по документации сделать. Но помогает далеко не всегда, ибо не получается сразу обычно что-то более хитрое, чем два байта переслать.
В чем смысл делать "инициализация и настройка по максимуму" вообще не понимаю. Разбираться с железом надо по любому постепенно и только с тем, которое СЕЙЧАС нужно. Шаг за шагом - GPIO помигать светодиодом, UART - поднять консольку, таймер - операционку поднять,.....


Но не все делают как вы всегда делаете. Мир многообразен.
zltigo
QUOTE (Tarbal @ Apr 12 2016, 16:01) *
Но не все делают как вы всегда делаете.

Да, я это очень хорошо знаю. Но в определеной мере такой подход к делу меня устраивает - к тому, кто смог написать надежную фирмварь ПОСЛЕ того, как были познаны все прелести гимморидальной болезни, как минимум, отношение почтительное. В какой-то степени это является моим куском хлеба с маслом.
x893
Особо вдаваться не хочется. Да и для разных типов процессоров держать в голове это всё - мало GВ под волосами. В общем-то каждый делает как ему удобнее.
zltigo
QUOTE (x893 @ Apr 12 2016, 19:33) *
Особо вдаваться не хочется. Да и для разных типов процессоров держать в голове это всё - мало GВ под волосами.

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

SasaVitebsk
Цитата(zltigo @ Apr 12 2016, 14:33) *
Я инода все-же такое делаю. Помогает, что срок жизни изделий по железу очень большой (10 лет типично), вот и становится разумным переодически вдыхать новую жизнь в старое железо. При этом рефакторинг тоже делаю.

Да тоже делаю. И, кстати, это одна из причин, по которой стараюсь библиотеки не применять. В последнем проекте, за время жизни даже CMSIS поменялся, сцуко. У меня ещё оставался на тот момент RCC (ну он один раз вначале проекта используется, для инициализации кварца.) Так пришлось переписать, так как IAR/CMSIS/HAL всё поменялось...

Цитата(x893 @ Apr 12 2016, 19:33) *
Особо вдаваться не хочется. Да и для разных типов процессоров держать в голове это всё - мало GВ под волосами. В общем-то каждый делает как ему удобнее.

Ещё раз повторяю. Вас никто уговаривать не собирается. Вы сами к этому придёте.
А держать в голове ничего не надо. Да и у программиста не держится ничего ... )))))
Я вообще сразу всё выкидываю. Иначе меня бы в толпе с расстояния пол километра видно было бы, по этой голове... ))
Я сейчас и даташит бегло читаю. Сразу открываю регистры и поехал ... )) Вся эта периферия более/ менее похожа. Нюансы - это незначительная часть.
zltigo
QUOTE (SasaVitebsk @ Apr 13 2016, 09:42) *
А держать в голове ничего не надо. Да и у программиста не держится ничего ... )))))
Я вообще сразу всё выкидываю. Иначе меня бы в толпе с расстояния пол километра видно было бы, по этой голове... ))

sm.gif точно!
ViKo
Не, одними регистрами не отделаешься. Приходится читать нужный раздел, и не раз. Всплывают всяческие зависимости от других периферийных устройств. А так, да, программирую регистры, не пропуская ни одного бита (умножаю на 0 ненужные). Последним часто программирую регистр, в котором включается это периферийное устройство. Обычно, работает. В-общем, команд - минимум.
KnightIgor
Цитата(ViKo @ Apr 13 2016, 07:56) *
Не, одними регистрами не отделаешься. Приходится читать нужный раздел, и не раз. Всплывают всяческие зависимости от других периферийных устройств. А так, да, программирую регистры, не пропуская ни одного бита (умножаю на 0 ненужные). Последним часто программирую регистр, в котором включается это периферийное устройство. Обычно, работает. В-общем, команд - минимум.

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

ОТ: По нескольку раз перечитывая разделы, Вы уже и пишете по нескольку раз wink.gif . SCNR.
ViKo
Цитата(KnightIgor @ Apr 13 2016, 10:17) *
ОТ: По нескольку раз перечитывая разделы, Вы уже и пишете по нескольку раз wink.gif . SCNR.

С АндроЕда, в метро. То есть связь, то нема. Однако, движок Электроникса пропускает такие голы.
Вот пример моего "творчества".
Код
  //  RCC->APB1RSTR |= RCC_APB1RSTR_TIM4RST;
  //  RCC->APB1RSTR = 0;
  
/*  Timer 4 задает интервал работы АЦП для измерения напряжений VREG, VACC  */
  TIM4->CR2 =
    TIM_CR2_CCDS         * 0 |    // Capture/Compare DMA Selection
    TIM_CR2_MMS_0        * 2 |    // Master Mode Selection: Update
    TIM_CR2_TI1S         * 0;    // TI1 Selection
  TIM4->SMCR = 0;
  TIM4->DIER = 0;

//  TIM4->CCMR1, TIM4->CCMR2 не используются
//  TIM4->CCER не используется
//  TIM4->CNT = 60E3 - 5;
  TIM4->PSC = PCLK1 * 2 / 1E3 - 1;    // Prescaler: 1 kHz, 1 ms
  TIM4->ARR = 60E3 - 1;            // Auto-reload: 60 s
//  Note that the actual counter enable signal CNT_EN is set 1 clock cycle after CEN.
  TIM4->CR1 =
    TIM_CR1_CEN          * 1 |    // Counter enable
    TIM_CR1_UDIS         * 0 |    // Update disable
    TIM_CR1_URS          * 0 |    // Update request source: Overflow, UG bit...
    TIM_CR1_OPM          * 0 |    // One pulse mode
    TIM_CR1_DIR          * 0 |    // Direction: Up
    TIM_CR1_CMS_0        * 0 |    // Center-aligned mode selection
    TIM_CR1_ARPE         * 1 |    // Auto-reload preload enable: buffered
    TIM_CR1_CKD_0        * 0;    // Clock division
  //  __nop(); __nop(); __nop(); __nop();
  //  DELAY(1333, _US);

/*  Так как Prescale Buffer обновляется по Update Event, то его нужно создать  */
  TIM4->EGR = TIM_EGR_UG;        // Update Generation
  //  TIM4->SR = 0;
zltigo
QUOTE (ViKo @ Apr 13 2016, 09:56) *
Не, одними регистрами не отделаешься. Приходится читать нужный раздел, и не раз. Всплывают всяческие зависимости от других периферийных устройств. А так, да, программирую регистры, не пропуская ни одного бита (умножаю на 0 ненужные).

Чрезмерно кучеряво с "умножением". Да и понимания не добавляет, ибо в Вашем-же примере
CODE
TIM_CR2_MMS_0        * 2

Я, ествественно понимаю, от чего на два, но если бы в Вашем-же стиле было написано
CODE
TIM_CR2_MMS_0        * 1

То для читающего никак не следует, что можно умножать на какое-то другое число и где предел? на 999 можно sm.gif?
Посему подобное нужно описывать или тупо все
TIM_CR2_MMS_0
TIM_CR2_MMS_1
....
Или, привычнее для меня, хотя и без защиты на 999 sm.gif, но игнорировать залезание в другие поля при указании 999 это можно и нужно.
TIM_CR2_MMS(x)
В упоминании незначаших битов особого смысла не вижу, поскольку надо или явно задекларировать, или просто посмотреть в хидере ВСЕ биты, причем с КОММЕНТАРИЯМИ. Редактор ДОЛЖЕН уметь работать с TAG и посмотреть в хидере выливается в один хоткей. Если перед глазами будет все время маячить такая крастота со множителями, то лично у меня просто глаза разбегутся и замылятся.
ViKo
У меня все биты с комментариями. В комментарии до двоеточия - документированное описание бита (из хидера), после двоеточия - конкретная выбранная функция.
И, вообще, все биты, что есть в устройстве. Ни один не пропущен (кроме битовых полей, из которых использую младший, умножая; конкретную функцию задает-то все поле). И я могу:
1. Легко изменить режим работы, меняя нолики на единички, или одно число на другое.
2. Использовать этот фрагмент, как заготовку, в другом проекте.
Умножаю на столько, сколько описано в руководстве для этого поля. Конкретно, для показанного случая, читаем:
Цитата
Bits 6:4 MMS[2:0]: Master mode selection
These bits allow to select the information to be sent in master mode to slave timers for
synchronization (TRGO). The combination is as follows:
000: Reset - the UG bit from the TIMx_EGR register is used as trigger output (TRGO). If the
reset is generated by the trigger input (slave mode controller configured in reset mode) then
the signal on TRGO is delayed compared to the actual reset.
001: Enable - the Counter enable signal, CNT_EN, is used as trigger output (TRGO). It is
useful to start several timers at the same time or to control a window in which a slave timer is
enabled. The Counter Enable signal is generated by a logic OR between CEN control bit
and the trigger input when configured in gated mode.
When the Counter Enable signal is controlled by the trigger input, there is a delay on TRGO,
except if the master/slave mode is selected (see the MSM bit description in TIMx_SMCR
register).
010: Update - The update event is selected as trigger output (TRGO). For instance a master
timer can then be used as a prescaler for a slave timer.
011: Compare Pulse - The trigger output send a positive pulse when the CC1IF flag is to be
set (even if it was already high), as soon as a capture or a compare match occurred.
(TRGO)
100: Compare - OC1REF signal is used as trigger output (TRGO)
101: Compare - OC2REF signal is used as trigger output (TRGO)
110: Compare - OC3REF signal is used as trigger output (TRGO)
111: Compare - OC4REF signal is used as trigger output (TRGO)

Защиты от превышения нет. Ну, так, мало ли что кому в голову взбредет. Можно и однобитовую переменную умножить на 999, если мозгов нет.
То, что бит не один, а целое поле, видно по его названию, где в конце всегда стоит _0. Были косяки в хидерах, но они исправляются.
zltigo
QUOTE (ViKo @ Apr 13 2016, 12:58) *
У меня все биты с комментариями.

Вижу. Это и ДОПОЛНИТЕЛЬНО и напрягает.
QUOTE
1. Легко изменить режим работы, меняя нолики на единички, или одно число на другое.

А НЕ изменить при этом комментарий ЕЩЕ проще sad.gif. По этой причине ститя комментирования подобного Вышему категорически избегаю.
QUOTE
Защиты от превышения нет. Ну, так, мало ли что кому в голову взбредет. Можно и однобитовую переменную умножить на 999, если мозгов нет.

А где граница наличия мозгов? Умножение на 3 это есть мозги, или уже нет? sm.gif
QUOTE
То, что бит не один, а целое поле, видно по его названию, где в конце всегда стоит _0.

Это Ваше личное знание. Я первым делом-бы подумал, что это таки значение поля. Наверное мозгов нет ;(
ViKo
Цитата(zltigo @ Apr 13 2016, 13:20) *
Это Ваше личное знание. Я первым делом-бы подумал, что это таки значение поля. Наверное мозгов нет ;(

Основано на изучении кейловского хидера. Пример:
Код
#define  PWR_CR_PLS                          ((uint32_t)0x000000E0)     /*!< PLS[2:0] bits (PVD Level Selection) */
#define  PWR_CR_PLS_0                        ((uint32_t)0x00000020)     /*!< Bit 0 */
#define  PWR_CR_PLS_1                        ((uint32_t)0x00000040)     /*!< Bit 1 */
#define  PWR_CR_PLS_2                        ((uint32_t)0x00000080)     /*!< Bit 2 */

А значение поля у них кодируется иначе:
Код
#define  PWR_CR_PLS_LEV0                     ((uint32_t)0x00000000)     /*!< PVD level 0 */
#define  PWR_CR_PLS_LEV1                     ((uint32_t)0x00000020)     /*!< PVD level 1 */
#define  PWR_CR_PLS_LEV2                     ((uint32_t)0x00000040)     /*!< PVD level 2 */
#define  PWR_CR_PLS_LEV3                     ((uint32_t)0x00000060)     /*!< PVD level 3 */
#define  PWR_CR_PLS_LEV4                     ((uint32_t)0x00000080)     /*!< PVD level 4 */
#define  PWR_CR_PLS_LEV5                     ((uint32_t)0x000000A0)     /*!< PVD level 5 */
#define  PWR_CR_PLS_LEV6                     ((uint32_t)0x000000C0)     /*!< PVD level 6 */
#define  PWR_CR_PLS_LEV7                     ((uint32_t)0x000000E0)     /*!< PVD level 7 */

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

P.S. Насчет мозгов можно сомневаться, а вот объективности в суждениях точно не хватает. Какие же упертые, эти латыши. Что один, что другой. biggrin.gif
Сергей Борщ
QUOTE (ViKo @ Apr 13 2016, 12:24) *
Вот тогда на помощь приходит красивое решение - умножить младший бит.
Не самое красивое решение, хотя я тоже с такого начинал. Сейчас пишу так:
CODE
2 * (PWR_CR_PLS & -PWR_CR_PLS)
У такой записи на лбу вырублено "я - битовое поле" и она работает даже если авторы заголовочного файла забыли определить отдельные биты.

QUOTE (ViKo @ Apr 13 2016, 12:24) *
Какие же упертые, эти латыши
Если это был намек в мой адрес - то я не латыш, я русский. Но мы оба латвийцы, да. Точно также как не каждый россиянин является русским. С белорусами в этом плане сложнее sm.gif
scifi
Цитата(Сергей Борщ @ Apr 13 2016, 14:23) *
Код
2 * (PWR_CR_PLS & -PWR_CR_PLS)
У такой записи на лбу вырублено "я - битовое поле" и она работает даже если авторы заголовочного файла забыли определить отдельные биты.

Чем дальше в лес, тем толще партизаны cranky.gif
ViKo
Цитата(Сергей Борщ @ Apr 13 2016, 14:23) *
Не самое красивое решение, хотя я тоже с такого начинал. Сейчас пишу так:
Код
2 * (PWR_CR_PLS & -PWR_CR_PLS)
У такой записи на лбу вырублено "я - битовое поле" и она работает даже если авторы заголовочного файла забыли определить отдельные биты.

Можно поспорить, что красивее. Но не стоит. Ваше решение я помню. Применял именно там, где хидерописатели напутали с описанием битов латентности флэш.
Цитата
Если это был намек в мой адрес - то я не латыш, я русский. Но мы оба латвийцы, да. Точно также как не каждый россиянин является русским. С белорусами в этом плане сложнее sm.gif

Тогда - латвийцы. rolleyes.gif
В Беларуси тоже много национальностей. Я сам - космополит наполовину. rolleyes.gif
zltigo
QUOTE (ViKo @ Apr 13 2016, 13:24) *
Основано на изучении кейловского хидера. Пример:
CODE
#define  PWR_CR_PLS_0                        ((uint32_t)0x00000020)     /*!< Bit 0 */
#define  PWR_CR_PLS_1                        ((uint32_t)0x00000040)     /*!< Bit 1 */
#define  PWR_CR_PLS_2                        ((uint32_t)0x00000080)     /*!< Bit 2 */

Тут как значения битов, а не только _0 с расчетом на умножение. Совершенно обыденно.
QUOTE
Если битов в поле больше трех, то описывать все их комбинации - мазохизм. Их и нет в хидере. Вот тогда на помощь приходит красивое решение - умножить младший бит.

PWR_CR_PLS_0*7 для получения (PWR_CR_PLS_0|PWR_CR_PLS_1|PWR_CR_PLS_2) Что-то мне это нифига красивым не кажется.
PWR_CR_PLS(7) - приемлимо. А лучше в таком выражении эту семерку задефинировать:
#define PLS_OC4REF (7)
И получим:
PWR_CR_PLS(PLS_OC4REF)

, что читабельнее и БЕЗОШИБОЧНЕЕ комментариев при изменениях. Причем расписывать все комбинации сразу нет никакой необходимости. Нужные режимы добавляются в процессе работы. Получается никак не более трудоемко, чем комментарии.

QUOTE (Сергей Борщ @ Apr 13 2016, 14:23) *
Не самое красивое решение, хотя я тоже с такого начинал. Сейчас пишу так:
CODE
2 * (PWR_CR_PLS & -PWR_CR_PLS)
У такой записи на лбу вырублено "я - битовое поле" и она работает даже если авторы заголовочного файла забыли определить отдельные биты.

Такое нужно в дополнительную обертку заворачивать. Иначе ЧЕЛОВЕЧЕСКИЙ глаз таки режет sad.gif
AHTOXA
Цитата(Сергей Борщ @ Apr 13 2016, 16:23) *
Не самое красивое решение, хотя я тоже с такого начинал. Сейчас пишу так:
Код
2 * (PWR_CR_PLS & -PWR_CR_PLS)
У такой записи на лбу вырублено "я - битовое поле" и она работает даже если авторы заголовочного файла забыли определить отдельные биты.

Ничего себе, "вырублено на лбу". Такую запись сходу поймут полтора человека из тысячи, а подумав - ещё человек десять sm.gif
pitt
de gustibus non est disputandum
Сергей Борщ
QUOTE (AHTOXA @ Apr 13 2016, 15:28) *
Ничего себе, "вырублено на лбу". Такую запись сходу поймут полтора человека из тысячи, а подумав - ещё человек десять sm.gif
Я в том смысле, что такая запись позвляет отличать битовое поле от одиночных битов:
CODE
    RCC->BDCR = 0
        | 0 * RCC_BDCR_BDRST
        | 0 * RCC_BDCR_RTCEN
        | 3 * (RCC_BDCR_RTCSEL &-RCC_BDCR_RTCSEL)   // 0 - no clk, 1 - LSE, 2 - LSI, 3 - HSE
        | 0 * RCC_BDCR_LSEBYP
        | 0 * RCC_BDCR_LSEON
       ;

Tanya
Вот еще добавлю...
Вдруг после очередного обновления пресловутого КУБа обнаружилось, что после старта АЦП с ДМА второй АЦП уже не стартует нормально.
Подробнее. При пошаговом прохождении в отладчике все как бы нормально, что еще противнее. Лень было разбираться.
Если запустить первый АЦП с внешним запуском, а потом второй АЦП, то так можно обойти проблему.
Где еще зарыли ОНИ подводные камни?
А в старом - я его предусмотрительно оставила, - все нормально идет.
Конечно, основной плюс КУБа в скорости создания инициализации. Особенно для особенно ленивых.
AHTOXA
Цитата(Сергей Борщ @ Apr 13 2016, 18:43) *
Я в том смысле, что такая запись позвляет отличать битовое поле от одиночных битов:

Сейчас пришла в голову мысль: можно завернуть это в constexpr-функцию, и пользовать её. Причём (это моё личное предпочтение) лучше сделать не маску, а номер бита, чтоб было не умножение, а сдвиг. То есть, где-то в заголовочнике:
Код
constexpr uint32_t CountTrailing0(uint32_t mask)
{
    return mask ? __builtin_ctz(mask) : sizeof(mask) * __CHAR_BIT__;
}

И где угодно:
Код
   RCC->BDCR = 0
        | 0 * RCC_BDCR_BDRST
        | 0 * RCC_BDCR_RTCEN
        | (3 << CountTrailing0(RCC_BDCR_RTCSEL))   // 0 - no clk, 1 - LSE, 2 - LSI, 3 - HSE
        | 0 * RCC_BDCR_LSEBYP
        | 0 * RCC_BDCR_LSEON
     ;

Так, возможно, число понявших немножко увеличитсяsm.gif
С другой стороны, это только C++, причём C++11. Но я, наверное, буду пользовать.
Ruslan1
Цитата(Tanya @ Apr 13 2016, 18:41) *
Конечно, основной плюс КУБа в скорости создания инициализации. Особенно для особенно ленивых.

Для меня основное преимущество Куба- это графическая распиновка, помощь при распределении ног и привязанных к этим пинам ресурсов, а также красивое документирование этого. Вот за это им честь-хвала и поклоны поясные.
pitt
Цитата(Tanya @ Apr 13 2016, 11:41) *
Вот еще добавлю...
Вдруг после очередного обновления пресловутого КУБа обнаружилось, что после старта АЦП с ДМА второй АЦП уже не стартует нормально.
Подробнее. При пошаговом прохождении в отладчике все как бы нормально, что еще противнее. Лень было разбираться.
Если запустить первый АЦП с внешним запуском, а потом второй АЦП, то так можно обойти проблему.
Где еще зарыли ОНИ подводные камни?
А в старом - я его предусмотрительно оставила, - все нормально идет.
Конечно, основной плюс КУБа в скорости создания инициализации. Особенно для особенно ленивых.

К сожалению, железо развивается быстрее, чем мы накапливаем знания. Документация STM отвратительная и подручная Индия есть не у всех... Короче, слишком часто скорость перевешивает качество и это, по-видимому, чем дальше, тем больше будет основным фактором. C'est la vie.
Baser
Цитата
Код
2 * (PWR_CR_PLS & -PWR_CR_PLS)

У такой записи на лбу вырублено "я - битовое поле" и она работает даже если авторы заголовочного файла забыли определить отдельные биты.

Цитата(AHTOXA @ Apr 13 2016, 16:28) *
Ничего себе, "вырублено на лбу". Такую запись сходу поймут полтора человека из тысячи, а подумав - ещё человек десять sm.gif

Думаю, даже меньше sm.gif
Это чисто математический трюк, не зная который в его смысл нужно въезжать.
Я вот так и не придумал, почему дополнение до машинного слова маски поля бит всегда дает единицу внутри этого поля.
Однако это так sm.gif
Так что такая запись будет "вырублена на лбу" только после её осмысления.
А стороннего бедолагу разработчика, которому нужно будет подправить этот код может ввести в глубокий ступор.

Цитата(pitt @ Apr 13 2016, 16:36) *
de gustibus non est disputandum

Абсолютно согласен, что начался спор о вкусах. Результат то все равно будет одинаковым.
_Pasha
ну не знаю... rolleyes.gif 0x11001000 * 5 = 0x55005000
это уже на лбу должно быть biggrin.gif
AHTOXA
Цитата(_Pasha @ Apr 13 2016, 21:56) *
ну не знаю... rolleyes.gif 0x11001000 * 5 = 0x55005000
это уже на лбу должно быть biggrin.gif

Речь не об этом, а о:
0x30 & -0x30 = 0x10
Огурцов
Цитата(Tanya @ Apr 13 2016, 15:41) *
Конечно, основной плюс КУБа в скорости создания инициализации. Особенно для особенно ленивых.

лениво - написать один раз свою инициализацию и затем копипастить в везде
а каждый раз разбираться с новыми интересными чужими граблями, особенно прикольно в поле - это надо быть весьма и весьма активным и весёлым человеком
ViKo
Скажите уже, что мой способ - и простой, и красивый.
Таня, разбираться надо не с Кубом, а с регистрами. Регистры описывали творцы, а Куб создали ремесленники (изучившие регистры).
ViKo
Цитата(AHTOXA @ Apr 13 2016, 20:28) *
Речь не об этом, а о:
0x30 & -0x30 = 0x10

Ага. Это есть трюк. Понятный, когда прикинешь к носу. Но даже автор (Сергей Борщ) в одной из тем описАлся, выдав nnn & ~nnn вместо nnn & -nnn.
Obam
Цитата(ViKo @ Apr 14 2016, 00:56) *
Ага. Это есть трюк.


Hacker's Delight by Henry S. Warren, "Алгоритмические трюки для программистов".
Сергей Борщ
QUOTE (ViKo @ Apr 13 2016, 22:56) *
Ага. Это есть трюк. Понятный, когда прикинешь к носу.
2 + 2 = 4. Тоже трюк. Не использовать?
AHTOXA
Цитата(Сергей Борщ @ Apr 14 2016, 14:27) *
2 + 2 = 4. Тоже трюк. Не использовать?

Тут простая математика. А там - именно что трюк. Насколько я понимаю, он базируется на том, что числа представлены в дополнительном коде. И единичка получается из-за несимметричности представления положительных и отрицательных чисел. Если же числа будут не в дополнительном коде, то трюк не сработает.
Kabdim
Я извиняюсь, но почему бы не использовать структуры с битовыми полями? В них можно запихивать и энумы.

Код
    #include <iostream>
    using namespace std;
    
    enum BOOL {
        f=0,
        t=1
    };
    
    struct A {
        BOOL b:1;
    };
    
    int main()
    {
        A a;
        a.b = t;
        if (a.b == t)
        {
            cout << "bit fields";
        }
        return 0;
    }
AlexandrY
Цитата(Kabdim @ Apr 14 2016, 15:17) *
Я извиняюсь, но почему бы не использовать структуры с битовыми полями? В них можно запихивать и энумы.


Потому что имена уже определены в хидерах.
Большинство тут пытается манипулировать с уже придуманными производителями HAL-ов именами.

Baser
Цитата(Kabdim @ Apr 14 2016, 15:17) *
Я извиняюсь, но почему бы не использовать структуры с битовыми полями? В них можно запихивать и энумы.

Битовые поля хороши всем, кроме невозможности получить реальный номер бита, где это поле расположено.
Битовое поле и было придумано, чтобы скрыть эту якобы ненужную информацию.
Как результат, проблематично одной командой сбросить/установить несколько битовых полей одновременно.
Многие фирмы сейчас предоставляют хидеры для МК, где регистры расписаны как в виде битовых полей, так и в виде обычных дефайнов с номерами или масками битов.
Kabdim
Цитата(AlexandrY @ Apr 14 2016, 15:30) *
Потому что имена уже определены в хидерах.
Большинство тут пытается манипулировать с уже придуманными производителями HAL-ов именами.

Это же не взаимоисключающие способы. То что не критично, с тем использовать HAL (причем на уровне оберток и автогенератора) и не париться. А для того блока для которого стоит задача высосать все соки и небольшой кусок хедеров переписать не зазорно. Всё равно своя библиотечка с нужным функционалом будет писаться дольше этого переписывания уже существующего, но при этом она будет значительно яснее.
Цитата(Baser @ Apr 14 2016, 15:37) *
Битовое поле и было придумано, чтобы скрыть эту якобы ненужную информацию.
Как результат, проблематично одной командой сбросить/установить несколько битовых полей одновременно.
Многие фирмы сейчас предоставляют хидеры для МК, где регистры расписаны как в виде битовых полей, так и в виде обычных дефайнов с номерами или масками битов.

Последовательное присвоение полям нормальный компилятор должен оптимизировать в 1 команду. Если очень надо именно определнную в старом стиле маску - есть тайпкасты. Да и опять же к регистрам можно обращаться одновременно и как к структурам и как описано в хидере производителя.
ViKo
Потому что у битовых полей их расположение в слове не определено точно, с какого бита начинается - с младшего или старшего, и может оказаться не совпадающим с расположением битов в регистрах.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.