Предполагаю использовать мьютекс для организации доступа к SPI. Т.е. при вызове функций записи или чтения через SPI доступ к интерфейсу выполняется через lock()/unlock().
В тоже время до запуска ОС через SPI необходимо сконфигурировать внешнее устройство используя те же функции записи/чтения (вызывающие lock()/unlock()).
Корректно ли выполнять вызовы lock()/unlock() до запуска OC? Требуется ли каким-либо образом привести объект-мьютекс в исходное состояние перед запуском ОС?
Заодно, прошу прокомментировать данную ситуацию в связи с другими сервисам межпроцессорного взаимодействия: событиями, сообщениями.
Цитата(&Rey @ Feb 16 2018, 11:08)

Предполагаю использовать мьютекс для организации доступа к SPI. Т.е. при вызове функций записи или чтения через SPI доступ к интерфейсу выполняется через lock()/unlock().
В тоже время до запуска ОС через SPI необходимо сконфигурировать внешнее устройство используя те же функции записи/чтения (вызывающие lock()/unlock()).
Корректно ли выполнять вызовы lock()/unlock() до запуска OC? Требуется ли каким-либо образом привести объект-мьютекс в исходное состояние перед запуском ОС?
Заодно, прошу прокомментировать данную ситуацию в связи с другими сервисам межпроцессорного взаимодействия: событиями, сообщениями.
lock() в данном случае выглядит безопасным - т.к. мутекс не залочен, то функция его залочит и вернётся. А вот unlock() вызовет планировщик, что ничем хорошим не кончится.
Не очень понял, зачем так делать. Ведь можно вызвать эту функцию инициализации SPI уже после старта оси перед входом в цикл процесса. Это корректно и безопасно.
Сергей Борщ
Feb 16 2018, 07:12
QUOTE (dxp @ Feb 16 2018, 09:05)

Не очень понял, зачем так делать. Ведь можно вызвать эту функцию инициализации SPI уже после старта оси.
Например, если хочется поместить эту функцию инициализации в конструктор глобального объекта.
AHTOXA
Feb 16 2018, 07:41
При вызове конструктора можно быть уверенным, что выполнение эксклюзивное, поэтому в конструкторах не нужны локи.
То есть, в качестве выхода можно предложить написать отдельную функцию инициализации, без локов/анлоков.
Цитата(Сергей Борщ @ Feb 16 2018, 14:12)

Например, если хочется поместить эту функцию инициализации в конструктор глобального объекта.
инициализация периферии из конструкторов глобальных объектов вообще, имхо, сомнительная затея.
Kabdim
Feb 16 2018, 08:37
Цитата(Сергей Борщ @ Feb 16 2018, 10:12)

Например, если хочется поместить эту функцию инициализации в конструктор глобального объекта.
Сколько подобных стилей написания конструкторов видел - всё время из-за них проблемы из-за недетерменированного порядка создания. Имхо конструктор долежн только инициализировать объект, и не должен применяться для старта работы, для старта должна быть отдельная функция.
Terminator
Feb 16 2018, 10:15
Я в своих проектах запускаю отдельную задачу которая выполняет все конструкторы. По окончанию задача убивается.
Для борьбы с порядком создания, использую god class.
Нагородил такое чтобы не париться с вызовами функций ос в конструкторах.
Цитата(Terminator @ Feb 16 2018, 17:15)

Я в своих проектах запускаю отдельную задачу которая выполняет все конструкторы. По окончанию задача убивается.
Для борьбы с порядком создания, использую god class.
Нагородил такое чтобы не париться с вызовами функций ос в конструкторах.
Это у вас конструкторы глобальных объектов вызываются в какой-то своей функции или вы объекты в ней и создаёте, обеспечивая тем самым гарантированный порядок вызова конструкторов?
Впервые применяю rtos в проекте, поэтому пока не в полной мере для меня понятен стиль программирования при её использовании. Без ОС применял следующий подход: в main сначала выполнялась инициализация периферии микроконтроллера, затем инициализация внешних по отношению к МК устройств и далее в цикле выполнялся конечный автомат(ы) состояний. Видимо сложно сразу отказаться от того к чему привык и текущий вариант у меня получился следующий. В main выполняется инициализация периферии контроллера, в частности SPI, затем через SPI инициализируется, например, графический контроллер и затем запускается ОС в процессах которых выполняется требуемая функциональность. Работа с графическим контроллером ведётся через SPI из нескольких процессов, поэтому выполняется через семафор, т.е. вызовом функций записи/чтения по SPI, начинающихся lock и заканчивающихся unlock соответствующего семафора. Эти же функции сейчас используются для конфигурирования графического контроллера до запуска ОС на этапе инициализации. Варианты с двумя копиями таких функций с lock/unlock и без, или дополнительной проверкой не кажутся правильными. Поэтому и возник вопрос: к чему может приводить вызовы функций сервисных объектов ОС, в частности семафора, до запуска ОС. Практика показывает, что, предварительно, по крайней мере, для семафора вызовы lock/unlock до старта ОС не к чему внешне заметному не приводят - после старта ОС всё работает логично. Потом, ради интереса посмотрю, что в данной ситуации происходит внутри ОС.
В итоге, скорее всего, воспользуюсь советом dxp и перемещу код использующий вызовы функций сервисов ОС внутрь одного из процессов до перехода в цикл.
Kabdim
Feb 16 2018, 11:14
Цитата(Terminator @ Feb 16 2018, 13:15)

Я в своих проектах запускаю отдельную задачу которая выполняет все конструкторы. По окончанию задача убивается.
Для борьбы с порядком создания, использую god class.
Не пойму как вы соединили богоклас и задачу с конструкторами. Не могли бы вы пояснить?
&Rey, иметь два варианта функций совсем не кривой вариант, а вполне рабочий. По сути функция всё равно одна, а вторая - это просто "обёртка". Ну, а перенос функции в процесс до цикла - это и есть аналог того, что вы описали про подход "main + superloop". По сути процесс в оси - это как бы свой собственный "main + superloop".
Вызов сервисов ос до старта является однозначно некорректным и опасным. Как уже сказано выше, при unlock'е будет вызван планировщик, который попытается перепланировать поток выполнения, но поскольку ещё ничего не началось, то у вас скорее всего перепланирования реально не происходит (это зависит от порядка приоритетов, на разных платформах он свой), поэтому внешне всё нормально. Но в другой ситуации это будет с грохотом падать. Поэтому так делать не надо.
Terminator
Feb 16 2018, 12:54
Цитата(dxp @ Feb 16 2018, 17:43)

Это у вас конструкторы глобальных объектов вызываются в какой-то своей функции или вы объекты в ней и создаёте, обеспечивая тем самым гарантированный порядок вызова конструкторов?
Вызываются конструкторы куском кода перенесённым из стартапа. Создания объектов избегаю всеми силами.
Цитата(Kabdim @ Feb 16 2018, 18:14)

Не пойму как вы соединили богоклас и задачу с конструкторами. Не могли бы вы пояснить?
В "богоклассе" вписаны все нужные мне объекты. Конструкторы вызываются в порядке объявления.
P. S. в качестве ос использую freertos, до scmrtos руки пока не дошли
Kabdim
Feb 16 2018, 14:15
А задача с конструкторами откуда взялась?
AHTOXA
Feb 16 2018, 15:48
Я делаю так:
- конструкторы выполняют только тривиальную инициализацию, которая не требует вызовов сервисов оси;
- Есть объект-флажок TEventFlag startEvent;
- все процессы, кроме самого приоритетного, начинают работу с вызова функции startEvent.wait();
- наиболее приоритетный процесс в начале вызывает sleep(1), чтобы все остальные процессы встали на ожидание флага
- затем наиболее приоритетный процесс спокойно выполняет всю инициализацию. С вызовами сервисов оси, если надо.
- по окончании инициализации наиболее приоритетный процесс вызывает startEvent.signal();
В новых версиях оси можно создавать процессы спящими (задав третий параметр шаблона process равным pssSuspended), поэтому можно делать проще:
- все процессы, кроме самого приоритетного, создать спящими;
- выполнить инициализацию в наиболее приоритетном процессе;
- разбудить остальные процессы.
Версия с вызовом конструкторов после старта оси мне нравится, но она не подходит для написания библиотек. Библиотечные объекты не могут полагаться на то, что будет использован модифицированный стартап.
Terminator
Feb 17 2018, 06:26
Цитата(Kabdim @ Feb 16 2018, 21:15)

А задача с конструкторами откуда взялась?
Руками написана конечно же.
Цитата(AHTOXA @ Feb 16 2018, 22:48)

Версия с вызовом конструкторов после старта оси мне нравится, но она не подходит для написания библиотек. Библиотечные объекты не могут полагаться на то, что будет использован модифицированный стартап.
Задача с конструкторами имеет наивысший приоритет. Если упростить, запуск оси вставлен в стартап перед вызовами конструкторов.
Имхо, проблем с библиотеками быть не должно. Хотя опыт использования библиотек у меня никакой.
AHTOXA
Feb 17 2018, 07:01
Цитата(Terminator @ Feb 17 2018, 11:26)

Если упростить, запуск оси вставлен в стартап перед вызовами конструкторов.
О, отличная мысль! Надо попробовать...
Сергей Борщ
Feb 17 2018, 07:25
QUOTE (AHTOXA @ Feb 17 2018, 09:01)

О, отличная мысль! Надо попробовать...
Попробовать запускать ОСь до вызова ее конструкторов?
AHTOXA
Feb 17 2018, 08:48
Да, засада...

)
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.