Могу ли я писать в векторе прерывания, а затем безопасно читать только в основном потоке? - PullRequest
0 голосов
/ 05 июня 2019

Мне нужна структура для моего прерывания, где я храню символы, поступающие через канал связи, в какое-то хранилище в mbed. Я пытался сделать это в ISR-безопасной очереди, но это может быть причиной того, что мой ISR не догоняет, что происходит.

Я хотел бы знать, могу ли я push_back() символ в прерывании, и это будет единственное прерывание, поэтому ему будет разрешено выполнить его полностью до завершения.

В main я проверю, не является ли вектор пустым, а затем прочту символ в начале, если это не так:

while (charThrough == 0) {
     if (myVect.size() > 0) {
         getChar = myvector.front();
         charThrough = 1;
     }
}

внутри функции, которую я буду вызывать, чтобы получить символ из вектора, который будет возвращать charThrough в main().

Ответы [ 2 ]

0 голосов
/ 06 июня 2019

Остальные верны, вы не много кода прерываете и вообще не используете динамическое распределение контейнеров на встроенных устройствах.Теперь поговорим о том, что может вам помочь.

В случае, если у вашего микрочипа есть возможность использовать прямой доступ к памяти (DMA), как у многих микросхем STM32, вы можете сделать нечто подобное без каких-либо программных прерываний.DMA может быть подключен через аппаратное обеспечение к вашему периферийному устройству, принимающему данные.Вы устанавливаете DMA таким образом, чтобы он записывал данные в простой массив.Перед началом операции чтения вы передаете указатель на DMA, куда он должен записать, и сколько места в буфере.Только после заполнения буфера вы получите прерывание от прямого доступа к памяти. Это сделано.

Если вы хотите продолжить чтение, но хотите обработать уже полученные данные, у вас может быть несколько буферов.Каждый раз в прерывании вы указываете DMA указатель на следующий буфер и помечаете предыдущий как готовый к обработке.Когда вы закончите обработку, вы пометите буфер как пустой.

Примечание: вы можете использовать std::array для встроенных целей, но в наши дни обычный массив уже очень легко использовать с циклами for-range.

0 голосов
/ 05 июня 2019

Если предположить, что это не какой-то замаскированный ПК, а настоящая встроенная система:

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

Вы не должны использовать std::vector вообще в большинстве встроенных систем, предпочтительным является std::array. Не следует также использовать выделение кучи.

Если вы по какой-то причине должны использовать стандартные библиотечные контейнеры, вам необходимо держать их подальше от любого аппаратного кода. Например, вы можете позволить вашему HAL работать с такими контейнерами, но фактические драйверы должны работать с необработанными массивами.

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

...