Jump to content

    

Вызовы функций сервисов ОС до её запуска

Предполагаю использовать мьютекс для организации доступа к SPI. Т.е. при вызове функций записи или чтения через SPI доступ к интерфейсу выполняется через lock()/unlock().

В тоже время до запуска ОС через SPI необходимо сконфигурировать внешнее устройство используя те же функции записи/чтения (вызывающие lock()/unlock()).

Корректно ли выполнять вызовы lock()/unlock() до запуска OC? Требуется ли каким-либо образом привести объект-мьютекс в исходное состояние перед запуском ОС?

Заодно, прошу прокомментировать данную ситуацию в связи с другими сервисам межпроцессорного взаимодействия: событиями, сообщениями.

 

Share this post


Link to post
Share on other sites
Предполагаю использовать мьютекс для организации доступа к SPI. Т.е. при вызове функций записи или чтения через SPI доступ к интерфейсу выполняется через lock()/unlock().

В тоже время до запуска ОС через SPI необходимо сконфигурировать внешнее устройство используя те же функции записи/чтения (вызывающие lock()/unlock()).

Корректно ли выполнять вызовы lock()/unlock() до запуска OC? Требуется ли каким-либо образом привести объект-мьютекс в исходное состояние перед запуском ОС?

Заодно, прошу прокомментировать данную ситуацию в связи с другими сервисам межпроцессорного взаимодействия: событиями, сообщениями.

lock() в данном случае выглядит безопасным - т.к. мутекс не залочен, то функция его залочит и вернётся. А вот unlock() вызовет планировщик, что ничем хорошим не кончится.

 

Не очень понял, зачем так делать. Ведь можно вызвать эту функцию инициализации SPI уже после старта оси перед входом в цикл процесса. Это корректно и безопасно.

Share this post


Link to post
Share on other sites
Не очень понял, зачем так делать. Ведь можно вызвать эту функцию инициализации SPI уже после старта оси.
Например, если хочется поместить эту функцию инициализации в конструктор глобального объекта.

 

Share this post


Link to post
Share on other sites

При вызове конструктора можно быть уверенным, что выполнение эксклюзивное, поэтому в конструкторах не нужны локи.

 

То есть, в качестве выхода можно предложить написать отдельную функцию инициализации, без локов/анлоков.

 

Share this post


Link to post
Share on other sites
Например, если хочется поместить эту функцию инициализации в конструктор глобального объекта.

инициализация периферии из конструкторов глобальных объектов вообще, имхо, сомнительная затея.

Share this post


Link to post
Share on other sites
Например, если хочется поместить эту функцию инициализации в конструктор глобального объекта.

Сколько подобных стилей написания конструкторов видел - всё время из-за них проблемы из-за недетерменированного порядка создания. Имхо конструктор долежн только инициализировать объект, и не должен применяться для старта работы, для старта должна быть отдельная функция.

Share this post


Link to post
Share on other sites

Я в своих проектах запускаю отдельную задачу которая выполняет все конструкторы. По окончанию задача убивается.

Для борьбы с порядком создания, использую god class.

 

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

 

Share this post


Link to post
Share on other sites
Я в своих проектах запускаю отдельную задачу которая выполняет все конструкторы. По окончанию задача убивается.

Для борьбы с порядком создания, использую god class.

 

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

Это у вас конструкторы глобальных объектов вызываются в какой-то своей функции или вы объекты в ней и создаёте, обеспечивая тем самым гарантированный порядок вызова конструкторов?

Share this post


Link to post
Share on other sites

Впервые применяю rtos в проекте, поэтому пока не в полной мере для меня понятен стиль программирования при её использовании. Без ОС применял следующий подход: в main сначала выполнялась инициализация периферии микроконтроллера, затем инициализация внешних по отношению к МК устройств и далее в цикле выполнялся конечный автомат(ы) состояний. Видимо сложно сразу отказаться от того к чему привык и текущий вариант у меня получился следующий. В main выполняется инициализация периферии контроллера, в частности SPI, затем через SPI инициализируется, например, графический контроллер и затем запускается ОС в процессах которых выполняется требуемая функциональность. Работа с графическим контроллером ведётся через SPI из нескольких процессов, поэтому выполняется через семафор, т.е. вызовом функций записи/чтения по SPI, начинающихся lock и заканчивающихся unlock соответствующего семафора. Эти же функции сейчас используются для конфигурирования графического контроллера до запуска ОС на этапе инициализации. Варианты с двумя копиями таких функций с lock/unlock и без, или дополнительной проверкой не кажутся правильными. Поэтому и возник вопрос: к чему может приводить вызовы функций сервисных объектов ОС, в частности семафора, до запуска ОС. Практика показывает, что, предварительно, по крайней мере, для семафора вызовы lock/unlock до старта ОС не к чему внешне заметному не приводят - после старта ОС всё работает логично. Потом, ради интереса посмотрю, что в данной ситуации происходит внутри ОС.

В итоге, скорее всего, воспользуюсь советом dxp и перемещу код использующий вызовы функций сервисов ОС внутрь одного из процессов до перехода в цикл.

Share this post


Link to post
Share on other sites
Я в своих проектах запускаю отдельную задачу которая выполняет все конструкторы. По окончанию задача убивается.

Для борьбы с порядком создания, использую god class.

Не пойму как вы соединили богоклас и задачу с конструкторами. Не могли бы вы пояснить?

Share this post


Link to post
Share on other sites

&Rey, иметь два варианта функций совсем не кривой вариант, а вполне рабочий. По сути функция всё равно одна, а вторая - это просто "обёртка". Ну, а перенос функции в процесс до цикла - это и есть аналог того, что вы описали про подход "main + superloop". По сути процесс в оси - это как бы свой собственный "main + superloop".

 

Вызов сервисов ос до старта является однозначно некорректным и опасным. Как уже сказано выше, при unlock'е будет вызван планировщик, который попытается перепланировать поток выполнения, но поскольку ещё ничего не началось, то у вас скорее всего перепланирования реально не происходит (это зависит от порядка приоритетов, на разных платформах он свой), поэтому внешне всё нормально. Но в другой ситуации это будет с грохотом падать. Поэтому так делать не надо.

Share this post


Link to post
Share on other sites
Это у вас конструкторы глобальных объектов вызываются в какой-то своей функции или вы объекты в ней и создаёте, обеспечивая тем самым гарантированный порядок вызова конструкторов?

Вызываются конструкторы куском кода перенесённым из стартапа. Создания объектов избегаю всеми силами.

 

Не пойму как вы соединили богоклас и задачу с конструкторами. Не могли бы вы пояснить?

В "богоклассе" вписаны все нужные мне объекты. Конструкторы вызываются в порядке объявления.

 

P. S. в качестве ос использую freertos, до scmrtos руки пока не дошли :(

Edited by Terminator

Share this post


Link to post
Share on other sites

А задача с конструкторами откуда взялась?

Share this post


Link to post
Share on other sites

Я делаю так:

  • конструкторы выполняют только тривиальную инициализацию, которая не требует вызовов сервисов оси;
  • Есть объект-флажок TEventFlag startEvent;
  • все процессы, кроме самого приоритетного, начинают работу с вызова функции startEvent.wait();
  • наиболее приоритетный процесс в начале вызывает sleep(1), чтобы все остальные процессы встали на ожидание флага
  • затем наиболее приоритетный процесс спокойно выполняет всю инициализацию. С вызовами сервисов оси, если надо.
  • по окончании инициализации наиболее приоритетный процесс вызывает startEvent.signal();

 

В новых версиях оси можно создавать процессы спящими (задав третий параметр шаблона process равным pssSuspended), поэтому можно делать проще:

  • все процессы, кроме самого приоритетного, создать спящими;
  • выполнить инициализацию в наиболее приоритетном процессе;
  • разбудить остальные процессы.

 

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

 

Share this post


Link to post
Share on other sites
А задача с конструкторами откуда взялась?

Руками написана конечно же.

 

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

Задача с конструкторами имеет наивысший приоритет. Если упростить, запуск оси вставлен в стартап перед вызовами конструкторов.

Имхо, проблем с библиотеками быть не должно. Хотя опыт использования библиотек у меня никакой.

Edited by Terminator

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this