|
|
  |
Библиотеки для STM32 |
|
|
|
Apr 21 2017, 08:55
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ Apr 21 2017, 10:34)  Вы хоть смотрели, как работают биты в регистре BSRR? Вся ваша галиматья не к месту. Ага, вижу, посмотрели таки! Гуд! Теперь согласны насчет галиматьи? Всё равно если есть возможность - это лучше чем если её нет. А применение найдётся. Цитата(Шаманъ @ Apr 21 2017, 10:42)  Атомарность внутри процессора. Ну почему-же. Если нет функции инверсии бита, а нужна именно инверсия, то как быть? Напишем что-то типа: if (PinOutputState()) PinReset(); else PinSet(); Если это не сделать атомарным (не завернуть в критическую секцию), а в программе данный пин управляется в разных задачах/ISR, то возможны коллизии.
|
|
|
|
|
Apr 21 2017, 08:59
|
Знающий
   
Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839

|
Цитата(jcxz @ Apr 21 2017, 11:55)  Если это не сделать атомарным (не завернуть в критическую секцию), а в программе данный пин управляется в разных задачах/ISR, то возможны коллизии. Это понятно, но я смотрю немного на более высокий уровень - какой смысл управлять одним и тем же пином из разных задач без какой-либо синхронизации? Как по мне, то никакого, а если делается синхронизация, то и проблемы нет. Вот когда речь идет про порт и управление разными пинами, то это очень реальный вариант, а с одним пином...
Сообщение отредактировал Шаманъ - Apr 21 2017, 09:01
|
|
|
|
|
Apr 21 2017, 09:06
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(Шаманъ @ Apr 21 2017, 13:42)  Этот пример мимо, ибо в данном случае идет речь о регистре BSRR и операциях с одним пином. Если изменение состояния пинов сделано через BSRR, то все будет прекрасно работать в двух потоках  Проблема может быть только если оба потока пытаются управлять одним и тем же пином, но это без какой-либо синхронизации не правильно по своей сути. Если у бабки были бы яйца... Только я в своем примере указал GPIO_ToggleBits() от стм, а они пользуют ODR, а не BSRR. а так согласен, запись в BSRR не создаст колизии, и тем не мение, осутствие аппаратного тогла требует лишней проверки выхода. Цитата какой смысл управлять одним и тем же пином из разных задач без какой-либо синхронизации? я не имел в виду одним пином.
|
|
|
|
|
Apr 21 2017, 09:08
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

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

Группа: Участник
Сообщений: 48
Регистрация: 15-07-06
Пользователь №: 18 836

|
Цитата(AHTOXA @ Apr 21 2017, 10:46)  А у тебя как это сделано? Я сначала тоже пробовал bitband, но без структуры, как у тебя, потому выигрыш был, но не такой заметный чтобы инлайнить полную инициализацию, а в дебаге размер вырос весьма значительно, плюс потеря поддержки F0. Потому в итоге остановился на отдельно функции инита, а встраивается только ее вызов. Внутри типичный код, который используется практически везде: читаем из MODER и пишем обратно(для F0 по-другому и не получится). Но проблема никуда не делась, хотя промежуточных состояний больше нет, в прерывании или другом потоке может быть изменен сам MODER и тогда будет записано старое, не измененное значение. Если это актуально, то можно написать потокобезопасные версии функций, которые будут запрещать прерывания на время модификаций всех 4-х регистров(и ODR), лично мне они пока не были нужны, т.к. до сих пор обходился прерываниями и регистры задающие режимы gpio в них не менял.
|
|
|
|
|
Apr 21 2017, 09:40
|
Знающий
   
Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839

|
Цитата(juvf @ Apr 21 2017, 12:06)  Если у бабки были бы яйца... Только я в своем примере указал GPIO_ToggleBits() от стм, а они пользуют ODR, а не BSRR. а так согласен, запись в BSRR не создаст колизии, и тем не мение, осутствие аппаратного тогла требует лишней проверки выхода. Что у стм не знаю, извиняюсь, но не пользовался никогда. Проверка (если Вы про ? или if) не обязательна, я уже приводил пример: Цитата(Шаманъ @ Apr 21 2017, 11:42)  Для внешнего устройства по идее достаточно (скажем для битов 0 и 7): GPIOx->BSRR = (~GPIOx->IDR & 0x81) | 0x00810000; Если же Вы про чтение порта, то я уже писал, что это плюс для аппаратного тоггла. Цитата(jcxz @ Apr 21 2017, 12:08)  Ну вот например: У Вас параллельная шина от Вашего МК к другому устройству, работает через GPIO, несколько сигналов данных и один - квитирования. Работает как шина DDR - т.е. обновление данных на шине фиксируется не по фронту или спаду, а по перепаду сигнала квитирования. Так получается можно быстрее данные передавать. А теперь представим, что для быстрого вывода на эту шину мы и линии данных и сигнал квитирования расположили в одном порту. Тогда чтобы вывести данные на эту шину достаточно одной операции записи. И никакие дополнительные средства обеспечения атомарности не нужны (типа запретов прерываний). Пример несколько футуристический и вызывает много вопросов "зачем?", самый главный - зачем писать данные из двух потоков в один порт без синхронизации (порт в данном случае не GPIO порт, а Ваш "виртуальный" а-ля DDR канал)? Мне кажется такое построение это некоторая ошибка в построении всей архитектуры системы или "синтетический пример".
Сообщение отредактировал Шаманъ - Apr 21 2017, 09:46
|
|
|
|
|
Apr 21 2017, 09:46
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 15-07-06
Пользователь №: 18 836

|
Цитата(Шаманъ @ Apr 21 2017, 12:40)  Пример несколько футуристический и вызывает много вопросов "зачем?", самый главный - зачем писать данные из двух потоков в один порт без синхронизации? Мне кажется такое построение это некоторая ошибка в построении всей архитектуры системы или "синтетический пример". Если запись любого числа битов в порт через BSRR атомарна, а она именно такова, то в принципе не нужно задумываться с каким портом в данный момент работаешь.
|
|
|
|
|
Apr 21 2017, 09:51
|
Знающий
   
Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839

|
Цитата(Reflector @ Apr 21 2017, 12:46)  Если запись любого числа битов в порт через BSRR атомарна, а она именно такова, то в принципе не нужно задумываться с каким портом в данный момент работаешь. Не, я не про то, подредактировал свой вопрос и уточнил про какой "порт" я говорил: Цитата(Шаманъ @ Apr 21 2017, 12:40)  Пример несколько футуристический и вызывает много вопросов "зачем?", самый главный - зачем писать данные из двух потоков в один порт без синхронизации (порт в данном случае не GPIO порт, а Ваш "виртуальный" а-ля DDR канал)?
|
|
|
|
|
Apr 21 2017, 09:53
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(Шаманъ @ Apr 21 2017, 14:40)  Что у стм не знаю, извиняюсь, но не пользовался никогда. Проверка (если Вы про ? или if) не обязательна, я уже приводил пример: Цитата Для внешнего устройства по идее достаточно (скажем для битов 0 и 7): GPIOx->BSRR = (~GPIOx->IDR & 0x81) | 0x00810000; а это разве не проверка? 1)читаем GPIOx->IDR (только правильнее будет ODR) 2)инвертируем ~GPIOx->IDR 3)& 0x81 4)| 0x00810000 5)записываем BSRR хотя согласен, для более одного пина, ваш вариант лучше, чем явные ? и if с аппаратным тогл, как в XMC4700/4800 1)GPIOx->BSRR = 0x0081'0081;//одна операция!!!
|
|
|
|
|
Apr 21 2017, 10:06
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 15-07-06
Пользователь №: 18 836

|
Цитата(jcxz @ Apr 21 2017, 12:55)  Запись атомарна, но в условии задачи указано "сигнал квитирования надо инвертировать". А значит на STM одной операцией записи не обойтись. Это да, но атомарную запись можно получить именно благодаря тому, что при одновременных установке и сбросе бита никакой инверсии нет. Если бы она была пришлось бы добавлять еще один регистр, так что при условии, что подобный регистр всего один была выбрана более полезная его функциональность.
|
|
|
|
|
Apr 21 2017, 10:08
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Шаманъ @ Apr 21 2017, 11:40)  Пример несколько футуристический и вызывает много вопросов "зачем?", самый главный - зачем писать данные из двух потоков в один порт без синхронизации (порт в данном случае не GPIO порт, а Ваш "виртуальный" а-ля DDR канал)? Мне кажется такое построение это некоторая ошибка в построении всей архитектуры системы или "синтетический пример". Понятно, что пример синтетический. В реальной практике у меня такой задачи не было. Но вот например у Вас есть внешняя память (SDRAM) скажем на нормальной шине. Вы же пишете в неё из разных задач/ISR не задумываясь об атомарности - это всё сделано на аппаратном уровне. Полезность такой записи из разных задач очевидна? А теперь представьте, что в МК нет внешней шины, или что эта шина не поддерживает устройство в которое надо писать. А это устройство имеет интерфейс, подобный DDR. И пакетные записи не нужны - каждая запись имеет значение (собственно этой записью передаётся некая команда в устройство). Все возможные схемы представить сложно, но имхо это - вполне жизненный вариант. У меня когда-то давно была практическая задача подобная этой, но там правда не надо было обращаться к шине из разных задач, но нужно было как можно быстрее передавать по такой шине. И при этом - на данном порту были ещё другие пины, которые трогать было нельзя. И в таком случае с регистром BSRR STM32 можно конечно реализовать такую передачу, но реализация получается более громоздкой чем на Infineon или LPC. Цитата(Reflector @ Apr 21 2017, 12:06)  Это да, но атомарную запись можно получить именно благодаря тому, что при одновременных установке и сбросе бита никакой инверсии нет. Если бы она была пришлось бы добавлять еще один регистр, так что при условии, что подобный регистр всего один была выбрана более полезная его функциональность. Зачем добавлять??? На Infineon я прекрасно и устанавливаю и сбрасываю и инвертирую пины одной операцией записи. BSRR = 1 << pin; //установка BSRR = 1 << pin + 16; //сброс BSRR = 0x10001 << pin; //инверсия
|
|
|
|
|
Apr 21 2017, 10:11
|
Участник

Группа: Участник
Сообщений: 48
Регистрация: 15-07-06
Пользователь №: 18 836

|
Цитата(jcxz @ Apr 21 2017, 13:08)  Зачем добавлять??? На Infineon я прекрасно и устанавливаю и сбрасываю и инвертирую пины одной операцией записи. Речь про STM32, у него только BSRR который дает возможность атомарно записать группу битов не затрагивая остальные пины. Если эту его способность заменить атомарной инверсией, то пользы будет меньше.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|