Официальный форум СВД Встраиваемые Системы
25 Мая, 2019, 15:51:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
 
 
 Сайт СВД ВС  Начало   Помощь Поиск Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как затормозить io_write в менеджере ресурсов?  (Прочитано 246 раз)
KA3AKOB
Пользователь

Сообщений: 18


« : 12 Апреля, 2019, 16:59:09 »

Разрабатывается специфическая плата для процессоров CPC304 под QNX6.4. Для неё пишу Resource Manager. Алгоритм передачи вкратце таков:
в пользовательской программе осуществляется вызов функции write(fd, buf, n); Эти n байтов надо записать в плату по прерыванию на каждый байт. Прерывание выставляется на шину ISA и обрабатывается обработчиком прерывания ISR(). После записи последнего байта ISR() должен выдать команду на выполнение массовой операции в плате над всеми байтами и по завершении этой операции в плате получить прерывание от платы, обработать его и завершить операцию записи.
Насколько я понимаю выполняется это так:
вызов write(fd, buf, n); преобразуется библиотекой менеджеров ресурсов в MsgSend(), происходит передиспетчеризация потоков и когда-нибудь получит управление поток менеджера ресурсов и библиотека вызовет callback-функцию io_write() в менеджере. io_write скопирует данные из msg в буфер доступный io_write() и ISR(), выдаст командой out8(addr, myByte) первый байт в плату и должен затормозиться до окончания передачи всех байтов, то есть: обработки всех прерываний от платы. ISR() должен подсчитывать передаваемые в плату байты и по окончании приёма последнего из них выдать в плату команду на массовую обработку всех байтов. По окончании этой обработки придёт прерывание от платы и тогда ISR() должен сделать что-то такое, чтобы io_write() растормозился и завершил работу. Ну, то есть вернулся в библиотечную функцию, а та уж сама сформирует MsgReply(). А по MsgReply() растормозится write(fd, buf, n); в клиентской программе. Согласно Кртену, если обработчик прерывания не хочет вызывать передиспетчеризацию потоков, то он возвращает (const struct sigevent *)NULL, а если надо возбудить передиспетчеризацию, то не NULL. Вопрос что?
В псевдокоде то, что хочу получить:

int io_write (resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb)
{
   // скопировать msg в буфер доступный и io_write() и ISR()
   // передать первый байт в плату
   out8(addr, myByte);
   // затормозиться до окончания обработки всех прерываний
   // выполнить завершающие действия
   return (_RESMGR_NPARTS (0)); // операция записи выполнена.
};

const struct sigevent * Td04Driver::main_isr (void *arg, int id)
{
   if (i<n) {  // обработаны не все байты
       out8(addr, myByte);
       return ((struct sigevent *)NULL);   // не возбуждать передиспетчеризацию
   } else {    // обработаны все байты
       // что-то ещё сделать
       return ((struct sigevent *)что_такое_надо_вернуть);      // возбуждать передиспетчеризацию
   }
}

Как известно из того же Кртена обработчик прерывания не может вызывать любые системные функции, а только очень ограниченный набор, типа InterruptMask(). Мне надо, чтобы по окончанию всех прерываний растормозился поток менеджера ресурсов и именно там где заторможен был в io_wite(), а не все какие есть потоки в системе. И мне надо, чтобы поток менеджера ресурсов не вернулся раньше завершения всех прерываний в пользовательскую программу с write().
« Последнее редактирование: 12 Апреля, 2019, 17:04:17 от KA3AKOB » Записан
Андрей Докучаев
Сотрудник СВД ВС
Ветеран

Сообщений: 737



WWW
« Ответ #1 : 12 Апреля, 2019, 17:43:24 »

Согласно Кртену, если обработчик прерывания не хочет вызывать передиспетчеризацию потоков, то он возвращает (const struct sigevent *)NULL, а если надо возбудить передиспетчеризацию, то не NULL

Не совсем верно. Повлиять напрямую на перепланирование напрямую корректно написанный ISR не может, поскольку это прерогатива ядра ОС. Возврат NULL или его отсутствие ставит в очередь ядра некий event, который косвенным образом на перепланирование влияние окажет. Таким образом "растормозить" все потоки в системе ISR не сможет.

Попробуйте следующее:
- io_write() после вызова out8() использует InterruptWait() для ожидания event-а от ISR;
- ISR после выполнения пакетной обработки данных отправляет event типа SIGEV_INTR.
Записан

Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP © 2002-2019 СВД Встраиваемые Системы.
При использовании материалов сайта ссылка на forum.kpda.ru обязательна.

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines | © Aiwan. Kolobok smiles | Sitemap
Valid XHTML 1.0! Valid CSS!
Сайт СВД ВС

В последний раз google посещал эту страницу 12 Апреля, 2019, 20:35:46