Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Библиотеки для STM32
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2, 3, 4, 5, 6, 7, 8
juvf
Цитата(AHTOXA @ Apr 20 2017, 14:18) *
ЗЫ. Я там вам ответил про варианты pin.h, возможно вы проглядели (тема растёт очень быстро).

Я видел. Полистал код. На заметку взял. Спасибо!!!


Всё? Расходимся! )))))))))))
jcxz
Цитата(Forger @ Apr 20 2017, 09:14) *
Не скажу, давно это было, не помню, где именно. Но почему-то запомнилось что int там был 16-битный.

На некоторых платформах и char бывает 16-битным laughing.gif

Цитата(AHTOXA @ Apr 20 2017, 11:18) *
Ну тогда bit-band. Есть везде, кроме L0.

И кроме M7.
Эдди
Цитата(jcxz @ Apr 20 2017, 12:42) *
На некоторых платформах и char бывает 16-битным

Пример - в студию!
juvf
Код
void toggle() { isLow() ? setToHigh() : setToLow(); }
Forger
Цитата(juvf @ Apr 20 2017, 12:54) *
Код
void toggle() { isLow() ? setToHigh() : setToLow(); }

Я лично не очень жалую такую форму условия со знаком "?", просто, дело вкуса, не более того.
juvf
Цитата(Forger @ Apr 20 2017, 15:25) *
Я не очень жалую такую форму условия со знаком "?"

такая же фигня. вообще не пользовать оператор ? до недавнего времени.... меня, когда "воспитывали", то по рукам били за несколько операторов в одной строке. И отучили. В принцепе согласен.... такие конструкции как
if(isLow()) return;
ухудшают читаемость кода. стал пользовать
if (isLow())
setToHigh();
else
setToLow();

после перешел на ?. нет портянок и нет в одной строке кучи операторов
jcxz
Цитата(Эдди @ Apr 20 2017, 11:48) *
Пример - в студию!

Семейство TMS320VC55xx в CCS.

Цитата(juvf @ Apr 20 2017, 12:29) *
согласен.... такие конструкции как
if(isLow()) return;
ухудшают читаемость кода. стал пользовать
...

Имхо наоборот: Портянки на несколько экранов вместо компактной записи - ухудшают читаемость.
Forger
Цитата(jcxz @ Apr 20 2017, 13:39) *
Портянки на несколько экранов вместо компактной записи - ухудшают читаемость.

+1
Шаманъ
Цитата(Reflector @ Apr 20 2017, 10:56) *
На радиокоте недавно спрашивали как записать 7 бит заданного байта в PD9, 5 бит в РВ4 и т.д.... Дали парочку ответов, лучший из которых выглядит так:
Код
GPIOD->BSRR = b & 0x80 ? GPIO_BSRR_BS9 : GPIO_BSRR_BR9;
GPIOB->BSRR = b & 0x20 ? GPIO_BSRR_BS4 : GPIO_BSRR_BR4;

Шаблонный код мог бы быть таким:
Код
GpioD<9>::write(b & 0x80);
GpioB<4>::write(b & 0x20);

Он понятнее и эффективнее, т.к. никаких проверок в нем нет.

Господа, нужно просто делать внимательно RTFM. BSRR регистр имеет замечательное свойство:
Цитата
Note: If both BSx and BRx are set, BSx has priority.

Поэтому задача решается очень просто без проверок:
Код
GPIOD->BSRR =  GPIO_BSRR_BR9 | ((b & 0x80) << 2);
GPIOB->BSRR = GPIO_BSRR_BR4 | ((b & 0x20) >> 1);


Это свойство полезно и в других задачах, обсуждаемых на последней паре страниц sm.gif.

Цитата
Какая сущность должна всем этим заниматься? Должен ли я для каждого USARTа закопать инициализацию пинов в какой-то общей функции инициализации? Считаю, что не должен

Как по мне, то если переинициализация не производится в процессе работы, то логично собрать все в одном месте. Особенно по части GPIO.
Эдди
Цитата(Шаманъ @ Apr 20 2017, 16:39) *
Поэтому задача решается очень просто без проверок:
Код
GPIOD->BSRR =  GPIO_BSRR_BR9 | ((b & 0x80) << 2);
GPIOB->BSRR = GPIO_BSRR_BR4 | ((b & 0x20) >> 1);

А не усугубят ли битовые сдвиги производительность этой и так тормозной операции?
Reflector
Цитата(Шаманъ @ Apr 20 2017, 16:39) *
Как по мне, то если переинициализация не производится в процессе работы, то логично собрать все в одном месте. Особенно по части GPIO.

Именно так, у меня вся инициализация настолько в одном месте, что я одной строкой инициализирую сам усарт вместе с портами, а рядом может быть инициализация USB или пина светодиода. Это возможно, т.к. класс пина владеет всей нужной информацией, а функция инициализации усарта знает в каком режиме эти пины нужно инициализировать. Если я не стану в нее передавать пины, то придется для каждого усарта добавить 2 строки их инициализации и тогда уже я должен думать какие-же для них нужно выбирать режимы. И это у меня 2 строки на усарт, а когда люди начинают 4 регистра gpio инициализировать вручную или когда они делают это через HAL, то получается намного больше.



Цитата(Шаманъ @ Apr 20 2017, 16:39) *
Господа, нужно просто делать внимательно RTFM. BSRR регистр имеет замечательное свойство:

Поэтому задача решается очень просто без проверок:
Код
GPIOD->BSRR =  GPIO_BSRR_BR9 | ((b & 0x80) << 2);
GPIOB->BSRR = GPIO_BSRR_BR4 | ((b & 0x20) >> 1);


Это свойство полезно и в других задачах, обсуждаемых на последней паре страниц sm.gif.

Правильно, метод write так и делает:
Код
static void write(bool data) { base()->BSRR = (0x10000 << pin) | (data << pin);    }
Obam
Цитата(Эдди @ Apr 20 2017, 17:59) *
А не усугубят ли битовые сдвиги производительность этой и так тормозной операции?

Битовые сдвиги у ARM бесплатные нативные. Ни у кого из МК нет операндом "шифтера".
jcxz
Цитата(Шаманъ @ Apr 20 2017, 15:39) *
Господа, нужно просто делать внимательно RTFM. BSRR регистр имеет замечательное свойство:

У Infineon XMC4700/4800 подобный регистр имеет ещё более замечательное свойство: при одновременной записи единички и в установку бита и в сброс бита, соответствующий бит инвертируется. Атомарно.
ViKo
Цитата(jcxz @ Apr 20 2017, 19:03) *
У Infineon XMC4700/4800 подобный регистр имеет ещё более замечательное свойство: при одновременной записи единички и в установку бита и в сброс бита, соответствующий бит инвертируется. Атомарно.

Это глупое свойство, не дающее никакой пользы.
jcxz
Цитата(ViKo @ Apr 20 2017, 19:48) *
Это глупое свойство, не дающее никакой пользы.

Если Вы не понимаете назначение чего-то, это не повод называть это глупым.
Axel
Цитата(ViKo @ Apr 20 2017, 20:48) *
Это глупое свойство, не дающее никакой пользы.


Не соглашусь. Если над генерить "жестко" комплементарные сигналы - очень даже... Правда запихнуть такое в либу проблематично (к вопросу об издержках подхода)
juvf
Цитата(Reflector @ Apr 20 2017, 19:21) *
Правильно, метод write так и делает:
Код
static void write(bool data) { base()->BSRR = (0x10000 << pin) | (data << pin);    }
Не ради спора... а чтоб расширить кругозор... искать ваши объяления/определения... классы/шаблоны..... поясните, если не сложно... или покажите сырцы GpioB<>

пусть b = 0xff;
GpioB<4>::write(b & 0x20); b & 0x20 даёт 0x20. что дальше? write() принимает bool. т.е. при передачи аргумента есть неявное преобразование uint8_t(0x20) в bool (0х01)? да и ещё и передача аргумента... т.е. копя data создается внутри write().
ViKo
Цитата(Axel @ Apr 21 2017, 05:52) *
Не соглашусь. Если над генерить "жестко" комплементарные сигналы - очень даже... Правда запихнуть такое в либу проблематично (к вопросу об издержках подхода)

Установить одновременно один вывод в 0, другой в 1? На STM32 - легко. Для этого не нужно инвертировать сигнал, посылая одновременно "установить" и "сбросить".
И, да, я тоже помню про приоритет при задании состояния.

Цитата(jcxz @ Apr 21 2017, 00:52) *
Если Вы не понимаете назначение чего-то, это не повод называть это глупым.

Прекрасно понимаю, что такое свойство мне [ ] не нужно.
STM согласна со мной, а не с вами. laughing.gif
Я и в ПЛИСке так управляю триггерами.
juvf
Цитата(ViKo @ Apr 21 2017, 10:00) *
STM согласна со мной, а не с вами. laughing.gif
Вы заблуждаетесь, они с вами не согласны. )))
Иногда требуется не просто установить в 1 или в 0, а переключить. Для чего - это отдельная тема. В некоторых процессорах, если не ошибаюсь, есть отдельный регистр для toggle. В стм32 его нет. Плохо. Но st такой функционал добавили в SPL.

Код
/**
  * @brief  Toggles the specified GPIO pins..
  * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
  *                      x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
  *                      x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
  * @param  GPIO_Pin: Specifies the pins to be toggled.
  * @retval None
  */
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);


Цитата
Установить одновременно один вывод в 0, другой в 1?

Цитата
Прекрасно понимаю, что такое свойство мне [ ] не нужно.
похоже вы не понимаете о чем речь идет. при чем тут один вывод и другой одновременно? тут всего один вывод требуется инвертировать.
ViKo
Цитата(juvf @ Apr 21 2017, 08:33) *
Вы заблуждаетесь, они с вами не согласны. )))
Иногда требуется не просто установить в 1 или в 0, а переключить. Для чего - это отдельная тема. В некоторых процессорах, если не ошибаюсь, есть отдельный регистр для toggle. В стм32 его нет. Плохо. Но st такой функционал добавили в SPL.
похоже вы не понимаете о чем речь идет. при чем тут один вывод и другой одновременно? тут всего один вывод требуется инвертировать.

Комплементарные сигналы - это всегда пара. А вы о чем?
Если мне нужно в одно время установить и сбросить несколько сигналов (в одном порту), я подготовлю нужное слово заранее и пошлю его в BSRR.
Если мне нужно инвертировать сигнал, я установлю или сброшу его в состояние, противоположное предыдущему. Что в библиотеке и сделано.
juvf
Цитата(ViKo @ Apr 20 2017, 22:48) *
Цитата
У Infineon XMC4700/4800 подобный регистр имеет ещё более замечательное свойство: при одновременной записи единички и в установку бита и в сброс бита, соответствующий бит инвертируется. Атомарно.

Это глупое свойство, не дающее никакой пользы.

Цитата
Комплементарные сигналы - это всегда пара. А вы о чем?
где тут пара?

jcxz говорит, что в Infineon XMC4700/4800 для инверсии вывода, одного вывода, нужно в BSRR регистр записать одновременно SetBit и ResetBit. При этом, вне зависимости от состояния вывода, он инвертируется. Эта операция атомарная и можно из разных потоков, даже из прерываний безопасно это делать. например для вывода РА0 это выглядит так
GPIOA->BSRR = GPIO_BSRR_BS0 | GPIO_BSRR_BR

2ViKo а про Комплементарные сигналы - тут я соглашусь, можно без тогла 2 вывода одновременно дёрнуть.
ViKo
Посмотрите сообщение, на которое я отвечал.
Я прекрасно понимаю, о чем говорится. Повторить - такое свойство [ ] не нужно.
Toggle - это Т-триггер. Поднимите руку, кто применял микросхемы таких триггеров.
juvf
Цитата(ViKo @ Apr 21 2017, 11:00) *
Посмотрите сообщение, на которое я отвечал.

я понял... просмотрел, уже отписал. тут я согласен
Цитата
Повторить - такое свойство [ ] не нужно.
а вот тут не понятно.... вы говорите, что если вам надо переключить бит, вы - установлю или сброшу его в состояние, противоположное предыдущему. Что в библиотеке и сделано. т.е. программно его инвертируете. Но аппаратное атомарное инвертирование - это для вас глупое свойство, не дающее никакой пользы. По мойму сами себе противоречите.
Польза в том, что инвертирование вывода будет за 1 машинный такт, атомарное, вот и всё!
ViKo
Заранее подготовлю слово для установки и слово для сброса. Когда нужно, пошлю.
За так(т) ничего не делается.

Предпочитаю конкретное поведение, не зависящее от того, в каком состоянии был до того.
Axel
Цитата(juvf @ Apr 21 2017, 08:56) *
...про Комплементарные сигналы - тут я соглашусь, можно без тогла 2 вывода одновременно дёрнуть.


Если нужно периодически (и быстро) тоглить комплементарные пины, и для этого надо ОДИН раз установить их состояние, а потом просто, не анализируя текущее состояние, писать в регистр КОНСТАНТУ...

Цитата
Поднимите руку, кто применял микросхемы таких триггеров.


А на транзисторах слабо? biggrin.gif
jcxz
Цитата(ViKo @ Apr 21 2017, 07:00) *
Прекрасно понимаю, что такое свойство мне [ ] не нужно.
STM согласна со мной, а не с вами. laughing.gif

Так оказывается это Вы в согласии с STM убрали из её периферии кучу полезного упростив её до неприличия, как то:
FIFO в различной периферии, dual- и quad-SPI, передачи "свЯзным списком" из DMA и т.п.
Вот оказывается кто виноват! biggrin.gif

Цитата(juvf @ Apr 21 2017, 08:24) *
я понял... просмотрел, уже отписал. тут я согласен
а вот тут не понятно.... вы говорите, что если вам надо переключить бит, вы - установлю или сброшу его в состояние, противоположное предыдущему. Что в библиотеке и сделано. т.е. программно его инвертируете. Но аппаратное атомарное инвертирование - это для вас глупое свойство, не дающее никакой пользы. По мойму сами себе противоречите.
Польза в том, что инвертирование вывода будет за 1 машинный такт, атомарное, вот и всё!

Человек не понимает понятие "атомарность". Что поделать.
Для одновременной установки и сброса (а это нужно например для формирования парафазных сигналов, но не только - есть другие применения, где очень сложно без такой опции)
если нет возможности инверсии пина, то ViKo придётся:
1. запретить прерывания;
2. считать слово из порта текущих значений пинов;
3. установить в нём бит;
4. сбросить в нём бит;
5. записать слово в порт текущих значений пинов;
6. разрешить прерывания.
Всего-то 6 операций вместо одной.
ViKo, Вы: а) понятия не имеет об атомарности операций и её необходимости? или б) троллите всех тут?
Reflector
Цитата(AHTOXA @ Apr 20 2017, 10:42) *
В вашем коде две проблемы:
1. Проблема с двухэтапной записью в MODER. Выше уже очень хорошо объяснили, что это нехорошо. Потому что ножка переводится в промежуточное состояние, которое может быть нежелательным. И при возникновении прерывания между двумя записями ножка может остаться в этом состоянии достаточно продолжительное время. Этого может быть достаточно, чтобы что-нибудь сжечь. Это реальная мина, потому что на столе может всё работать, а в продакшене может рвануть.

В твоем кода, кстати, то же самое. В MODER и еще двух регистрах режим задается выставлением двух битов, но при использовании bitband они выставляются по отдельности...
jcxz
Цитата(Axel @ Apr 21 2017, 08:57) *
Если нужно периодически (и быстро) тоглить комплементарные пины, и для этого надо ОДИН раз установить их состояние, а потом просто, не анализируя текущее состояние, писать в регистр КОНСТАНТУ...

Как вариант такого применения (я использовал это на практике):
Реализация передачи для soft-UART через таймер+DMA+GPIO - при наличии возможности инверсии пинов это делается очень легко простой DMA-транзакцией (без использования передачи "свЯзных списков") заранее подготовленного массива по одному адресу, без влияния на соседние пины и всего с одним прерыванием на байт по окончании передачи всего блока.
На МК где нет инверсии пина, это решается более громоздкой передачей "свЯзным списком" в перемежающие адреса регистров установки или сброса.
Либо (если в GPIO МК есть регистр маски пинов) - маскированием (но операция может быть конфликтной с другими подобными).
На STM32 это не решается никак из-за отсутствия инверсии пина и отсутствии передачи "свЯзным списком". Только дёргаться в прерывания на каждый бит, переключая адреса в "double buffer" DMA режиме. laughing.gif
Forger
Цитата(jcxz @ Apr 21 2017, 10:16) *
Как вариант такого применения (я использовал это на практике):
Реализация передачи для soft-UART через таймер+DMA+GPIO -

Какой суровый ногодрыг получается... wacko.gif
jcxz
Цитата(Forger @ Apr 21 2017, 09:28) *
Какой суровый ногодрыг получается... wacko.gif

Как раз для проца - совсем несуровый - его загрузка почти как с аппаратным UART получается - всего одно прерывание в конце блока. А если не жалко памяти, то можно и tx.FIFO эмулировать biggrin.gif

PS: Чой-то я ошибся - прогнал напраслину на STM32 rolleyes.gif
Сейчас глянул - у него же установка/сброс через один регистр делаются, значит такой soft-UART можно и на нём сделать. Что-то у меня в мыслях было, что это два разных регистра.... wacko.gif
Forger
Цитата(jcxz @ Apr 21 2017, 10:37) *
Как раз для проца - совсем несуровый - ...

Суровый в смысле отладки и тестирования. Такое, наверно, приходится применять, когда камень заменить нереально, т. к. уже понаделана куча плат. У вас тот случай? wink.gif
Reflector
Цитата(juvf @ Apr 21 2017, 06:04) *
пусть b = 0xff;
GpioB<4>::write(b & 0x20); b & 0x20 даёт 0x20. что дальше? write() принимает bool. т.е. при передачи аргумента есть неявное преобразование uint8_t(0x20) в bool (0х01)? да и ещё и передача аргумента... т.е. копя data создается внутри write().

Write всегда инлайнится, никакой копии data там не будет. Вот дизассм:
Код
0x20000844  ldr r3, [sp, #4]
0x20000846  ldr r2, [pc, #80]
0x20000848  ubfx r3, r3, #5, #1
0x2000084c  lsls r3, r3, #8
0x2000084e  orr.w r3, r3, #0x1000000
0x20000852  str r3, [r2, #24]

А это для для варианта с проверкой:
Код
// GPIOB->BSRR = (b & 0x20) ? GPIO_BSRR_BS4 : GPIO_BSRR_BR4;
0x20000844  ldr r2, [sp, #4]
0x20000846  ldr r3, [pc, #84]
0x20000848  tst.w r2, #32
0x2000084c  ite eq
0x2000084e  moveq.w r2, #1048576
0x20000852  movne r2, #16
0x20000854  str r2, [r3, #24]

Лишняя команда, лишние 2 байта, абсолютно не критично, но пострадала еще и наглядность, причем такой менее очевидный код еще и приходится для каждого пина писать заново.

ps.
Только я тут опечатался, не GpioB, он работает с маской группы битов, тогда как минимум нужно 4 заменить на 0x10, а PinB...
AHTOXA
Цитата(Reflector @ Apr 21 2017, 12:11) *
В твоем кода, кстати, то же самое. В MODER и еще двух регистрах режим задается выставлением двух битов, но при использовании bitband они выставляются по отдельности...

Да, есть такое. Но это лучше, чем испортить MODER при RMW из нескольких потоков.
Прерывания запрещать в настройке пина я не решился.

А у тебя как это сделано?
jcxz
Цитата(Forger @ Apr 21 2017, 09:42) *
Суровый в смысле отладки и тестирования. Такое, наверно, приходится применять, когда камень заменить нереально, т. к. уже понаделана куча плат. У вас тот случай? wink.gif

Не совсем. Где Вы возьмёте МК с 6 UART-ами например? При этом чтобы не экзотика какая и остальная периферия нормальная была.
Вот и выбрали LPC1778 заранее зная, что надо будет один из UART-ов программно эмулировать.
Forger
Цитата(jcxz @ Apr 21 2017, 10:46) *
Не совсем. Где Вы возьмёте МК с 6 UART-ами например?

Я и задачу-то такую не найду, где нужно стока uart ...
если позволяет бюджет изделия, в таком случае я бы поставил плис
Шаманъ
Цитата(juvf @ Apr 21 2017, 09:24) *
Польза в том, что инвертирование вывода будет за 1 машинный такт, атомарное, вот и всё!

Инвертирование за один такт пожалуй единственная реальная польза. Атомарность инвертированию одного пина не особо нужна, или у Вас есть пример, где она реально может понадобиться?

Цитата(jcxz @ Apr 21 2017, 10:16) *
Как вариант такого применения (я использовал это на практике):
Реализация передачи для soft-UART через таймер+DMA+GPIO
.................
На МК где нет инверсии пина, это решается более громоздкой передачей "свЯзным списком" в перемежающие адреса регистров установки или сброса.
Либо (если в GPIO МК есть регистр маски пинов) - маскированием (но операция может быть конфликтной с другими подобными).
На STM32 это не решается никак из-за отсутствия инверсии пина и отсутствии передачи "свЯзным списком".

Что-то я не совсем понимаю, а в чем проблема при наличии BSRR регистра проделать то же самое? Подготовили в памяти массив слов и шлем в BSRR, в конце блока прерывание.

Цитата(jcxz @ Apr 21 2017, 10:46) *
Где Вы возьмёте МК с 6 UART-ами например?

У того stmа, что сейчас лежит передо мной 8 UARTов, не уверен получится ли все их задействовать одновременно (в смысле распределения по ногам), но у меня не самый многоногий корпус wink.gif
jcxz
Цитата(Forger @ Apr 21 2017, 09:48) *
Я и задачу-то такую не найду, где нужно стока uart ...
если позволяет бюджет изделия, в таком случае я бы поставил плис

Бюджет не позволяет однозначно. Во-первых - стоимость самого устройства, во-вторых - стоимость разработки (нужно ещё ПЛИС программировать); в-третьих - стоимость сопровождения (как быть если обнаружится баг в прошивке ПЛИС? необходимо удалённое обновление её прошивки значит).
Да и зачем??? ПЛИС для доп. UART-а - это из пушки по воробьям.

Цитата(Шаманъ @ Apr 21 2017, 09:51) *
У того stmа, что сейчас лежит передо мной 8 UARTов, не уверен получится ли все их задействовать одновременно (в смысле распределения по ногам), но у меня не самый многоногий корпус wink.gif

Да, вот именно у STM32 есть проблема с одновременным задействованием всех этих UART. Даже если по ногам хватит, то не хватит по ресурсам - на все не хватит DMA, а работать без DMA и без FIFO в UART-е с кучей портов одновременно, когда есть и ещё более приоритетные прерывания - будет приводить к сбоям и потерям.

PS: Да, я имел в виду на тот момент не было подходящих МК (эта разработка была лет 7 назад). В более поздней подобной разработке использовали уже Tiva - там тоже есть 8 UART-ов причём полноценных - каждый с FIFO - можно работать с ними и без DMA.

Цитата(Шаманъ @ Apr 21 2017, 09:51) *
Что-то я не совсем понимаю, а в чем проблема при наличии BSRR регистра проделать то же самое? Подготовили в памяти массив слов и шлем в BSRR, в конце блока прерывание.

Я уже написал, что тут ошибся, не посмотрел что у STM это один регистр установки/сброса - см. пост выше.

Цитата(Шаманъ @ Apr 21 2017, 09:51) *
Атомарность инвертированию одного пина не особо нужна, или у Вас есть пример, где она реально может понадобиться?

В смысле? Какую атомарность имеете в виду? Атомарность операции внутри процессора или атомарность для внешнего устройства (правильный парафазный сигнал, фронт/спад в один момент)?
Forger
Цитата(jcxz @ Apr 21 2017, 10:57) *
Бюджет не позволяет однозначно. Во-первых - стоимость самого устройства, во-вторых - стоимость разработки (нужно ещё ПЛИС программировать);

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

Цитата
в-третьих - стоимость сопровождения (как быть если обнаружится баг в прошивке ПЛИС? необходимо удалённое обновление её прошивки значит).

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

Цитата
ПЛИС для доп. UART-а - это из пушки по воробьям.
Плис бывают разные )))


Как вариант без плис: MAX14830
jcxz
Цитата(Forger @ Apr 21 2017, 10:06) *
На кой менять прошивку, где работают только несколько одинаковых uart? Для такой тривиальной задачи имеет смысл сразу ее отладить и оттестировать.

Ну да... Гладко было на бумаге да забыли про овраги. Как показывает практика, даже в самой отлаженной и тривиальной задаче могут быть баги.
Наступали на эти грабли и очень больно. У Вас видно нет заказчиков с несколькими тысячами Ваших изделий раскиданных на тысячи км по глухой тайге. Да ещё когда устройство работает на объекте в режиме 24/7 и отключить его - огромная проблема. Стоимость ошибки в ПО и обновления ПО с приездом на объект тут получается просто фантастической. Я сам когда-то летал на вертолёте по этим объектам и обновлял прошивки. Рассказать про стоимость часа аренды вертолёта? cool.gif
С тех пор взяли за правило: если в изделии используются некие компоненты с прошивкой, то должна быть возможность удалённого обновления этой прошивки по протоколу работы устройства без его остановки в обязательном порядке. И это правило нас потом неоднократно выручало.

Цитата(Forger @ Apr 21 2017, 10:06) *
Плис бывают разные )))

Стоимость ПЛИС какой бы она ни была, всё равно выше 0. А это изделие предполагалось сделать бюджетным.
И ещё Вы забываете про стоимость изготовления. ПЛИС ещё прошить надо.
Forger
Цитата
И ещё Вы забываете про стоимость изготовления. ПЛИС ещё прошить надо.
Наверно, у вас работает очень дорогой настройшик - 2 минуты работы которого © "стоят тысячу фунтов" sm.gif
juvf
Цитата(Шаманъ @ Apr 21 2017, 12:51) *
Атомарность инвертированию одного пина не особо нужна, или у Вас есть пример, где она реально может понадобиться?
на вскидку один я уже писал в этой теме. на РА0 у вас CS, на РА5 у вас светодиод внешний вачдог. каждый пин дергается в отдельном потоке. Если использовать неатомарный тогл (GPIO_ToggleBits() ) для вачдога из SPL от STM, без критСекций/запрета прерываний/мьютексов на порта РА, то будет косяк.
Да даже без ОС: в главном while вы работаете с РB1, в прерывании PB2 - вот ещё случай.
jcxz
Цитата(Forger @ Apr 21 2017, 10:18) *
Наверно, у вас работает очень дорогой настройшик - 2 минуты работы которого © "стоят тысячу фунтов" sm.gif

Стоимость работы настройщика + стоимость ПЛИС (или чего там вместо) + стоимость написания ПО обновления прошивки.
Это на одной тарелке весов. На другой - стоимость написания soft-UART.
Сравните. Разница многократная.

Да - и как с этой ПЛИС взаимодействовать? Поди ещё и внешняя шина нужна? Ног в том проекте тоже не хватало.
Forger
Цитата(jcxz @ Apr 21 2017, 11:22) *
Да - и как с этой ПЛИС взаимодействовать? Поди ещё и внешняя шина нужна? Ног в том проекте тоже не хватало.

Вполне хватит одного SPI, как это сделано в MAX14830
ViKo
Цитата(jcxz @ Apr 21 2017, 10:06) *
Человек не понимает понятие "атомарность". Что поделать.
Для одновременной установки и сброса (а это нужно например для формирования парафазных сигналов, но не только - есть другие применения, где очень сложно без такой опции)
если нет возможности инверсии пина, то ViKo придётся:
1. запретить прерывания;
2. считать слово из порта текущих значений пинов;
3. установить в нём бит;
4. сбросить в нём бит;
5. записать слово в порт текущих значений пинов;
6. разрешить прерывания.
Всего-то 6 операций вместо одной.
ViKo, Вы: а) понятия не имеет об атомарности операций и её необходимости? или б) троллите всех тут?

Вы хоть смотрели, как работают биты в регистре BSRR? Вся ваша галиматья не к месту.
Ага, вижу, посмотрели таки! Гуд! Теперь согласны насчет галиматьи?
Шаманъ
Цитата(jcxz @ Apr 21 2017, 11:03) *
В смысле? Какую атомарность имеете в виду? Атомарность операции внутри процессора или атомарность для внешнего устройства (правильный парафазный сигнал, фронт/спад в один момент)?

Атомарность внутри процессора. Для внешнего устройства по идее достаточно (скажем для битов 0 и 7):
GPIOx->BSRR = (~GPIOx->IDR & 0x81) | 0x00810000;
Ну и изначально должно быть правильное состояние битов (например, GPIOx->BSRR = 0x00800001).


Цитата(juvf @ Apr 21 2017, 11:21) *
на вскидку один я уже писал в этой теме. на РА0 у вас CS, на РА5 у вас светодиод внешний вачдог. каждый пин дергается в отдельном потоке. Если использовать неатомарный тогл (GPIO_ToggleBits() ) для вачдога из SPL от STM, без критСекций/запрета прерываний/мьютексов на порта РА, то будет косяк.
Да даже без ОС: в главном while вы работаете с РB1, в прерывании PB2 - вот ещё случай.

Этот пример мимо, ибо в данном случае идет речь о регистре BSRR и операциях с одним пином. Если изменение состояния пинов сделано через BSRR, то все будет прекрасно работать в двух потоках sm.gif Проблема может быть только если оба потока пытаются управлять одним и тем же пином, но это без какой-либо синхронизации не правильно по своей сути.
jcxz
Цитата(ViKo @ Apr 21 2017, 10:34) *
Вы хоть смотрели, как работают биты в регистре BSRR? Вся ваша галиматья не к месту.
Ага, вижу, посмотрели таки! Гуд! Теперь согласны насчет галиматьи?

Всё равно если есть возможность - это лучше чем если её нет. А применение найдётся.

Цитата(Шаманъ @ Apr 21 2017, 10:42) *
Атомарность внутри процессора.

Ну почему-же.
Если нет функции инверсии бита, а нужна именно инверсия, то как быть?
Напишем что-то типа:
if (PinOutputState()) PinReset();
else PinSet();
Если это не сделать атомарным (не завернуть в критическую секцию), а в программе данный пин управляется в разных задачах/ISR, то возможны коллизии.
Шаманъ
Цитата(jcxz @ Apr 21 2017, 11:55) *
Если это не сделать атомарным (не завернуть в критическую секцию), а в программе данный пин управляется в разных задачах/ISR, то возможны коллизии.

Это понятно, но я смотрю немного на более высокий уровень - какой смысл управлять одним и тем же пином из разных задач без какой-либо синхронизации? Как по мне, то никакого, а если делается синхронизация, то и проблемы нет. Вот когда речь идет про порт и управление разными пинами, то это очень реальный вариант, а с одним пином...
juvf
Цитата(Шаманъ @ Apr 21 2017, 13:42) *
Этот пример мимо, ибо в данном случае идет речь о регистре BSRR и операциях с одним пином. Если изменение состояния пинов сделано через BSRR, то все будет прекрасно работать в двух потоках sm.gif Проблема может быть только если оба потока пытаются управлять одним и тем же пином, но это без какой-либо синхронизации не правильно по своей сути.
Если у бабки были бы яйца... Только я в своем примере указал GPIO_ToggleBits() от стм, а они пользуют ODR, а не BSRR. а так согласен, запись в BSRR не создаст колизии, и тем не мение, осутствие аппаратного тогла требует лишней проверки выхода.
Цитата
какой смысл управлять одним и тем же пином из разных задач без какой-либо синхронизации?
я не имел в виду одним пином.
jcxz
Цитата(Шаманъ @ Apr 21 2017, 10:59) *
Это понятно, но я смотрю немного на более высокий уровень - какой смысл управлять одним и тем же пином из разных задач без какой-либо синхронизации? Как по мне, то никакого, а если делается синхронизация, то и проблемы нет. Вот когда речь идет про порт и управление разными пинами, то это очень реальный вариант, а с одним пином...

Ну вот например:
У Вас параллельная шина от Вашего МК к другому устройству, работает через GPIO, несколько сигналов данных и один - квитирования.
Работает как шина DDR - т.е. обновление данных на шине фиксируется не по фронту или спаду, а по перепаду сигнала квитирования. Так получается можно быстрее данные передавать.
А теперь представим, что для быстрого вывода на эту шину мы и линии данных и сигнал квитирования расположили в одном порту.
Тогда чтобы вывести данные на эту шину достаточно одной операции записи. И никакие дополнительные средства обеспечения атомарности не нужны (типа запретов прерываний).
Reflector
Цитата(AHTOXA @ Apr 21 2017, 10:46) *
А у тебя как это сделано?

Я сначала тоже пробовал bitband, но без структуры, как у тебя, потому выигрыш был, но не такой заметный чтобы инлайнить полную инициализацию, а в дебаге размер вырос весьма значительно, плюс потеря поддержки F0. Потому в итоге остановился на отдельно функции инита, а встраивается только ее вызов. Внутри типичный код, который используется практически везде: читаем из MODER и пишем обратно(для F0 по-другому и не получится). Но проблема никуда не делась, хотя промежуточных состояний больше нет, в прерывании или другом потоке может быть изменен сам MODER и тогда будет записано старое, не измененное значение. Если это актуально, то можно написать потокобезопасные версии функций, которые будут запрещать прерывания на время модификаций всех 4-х регистров(и ODR), лично мне они пока не были нужны, т.к. до сих пор обходился прерываниями и регистры задающие режимы gpio в них не менял.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.