Перейти к содержанию
    

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

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

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

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

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

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

 

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

Изменено пользователем Terminator

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я делаю так:

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

 

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

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

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

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

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

Изменено пользователем Terminator

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...