Шрифт:
В самых ранних версиях QNX (семейство QNX2) программирование драйверов устройств было чем-то из области черной магии. В QNX4 это тоже поначалу была загадочная вещь, но затем, в конце концов, появилось несколько примеров программ. В QNX/Neutrino этому вопросу посвящены книги и учебные курсы. И, как оказалось, модели драйверов в QNX/ Neutrino и QNX4 на архитектурном уровне достаточно сходны. В то время как в QNX4 была кромешная путаница вокруг того, что такое «функции установления соединения» и что такое «функции ввода-вывода», в QNX/Neutrino все четко разделено. Также под QNX4 вы (разработчик драйвера устройства) должны были выполнять большую часть работы (программирование основного цикла обработки сообщений, сопоставление контекста каждому сообщению ввода-вывода, и т.д.) самостоятельно. В QNX/Neutrino все это в значительной степени упрощено введением библиотеки администратора ресурсов.
Одно из самых существенных отличий QNX/Neutrino от QNX4 в отношении встраиваемости состоит в том, что QNX/Neutrino поддерживает процессоры MIPS и PPC (Power PC). QNX4 изначально была «дома» на IBM PC с их BIOS и «очень» стандартным набором аппаратных средств, QNX/Neutrino же одинаково по-домашнему чувствует себя на разных платформах с BIOS (или монитором ПЗУ) или без нее, а также на нестандартной аппаратуре, комплектация которой выбирается изготовителем (и часто без учета требований ОС). Это означает, что ядро QNX/Neutrino должно было обеспечивать поддержку исходящих вызовов (callouts), чтобы вы могли, например, задать свой тип контроллера прерываний и работать на этих аппаратных средствах без необходимости приобретения лицензии на исходный текст операционной системы.
Другая группа изменений, которые вы заметите при переносе приложений из QNX4 в QNX/Neutrino, особенно на другие платформы, касается того, что процессоры MIPS и PPC уж больно вычурны по части выравнивания. Вы не можете обращаться к N-байтовому объекту иначе чем по адресу, кратному N. При работе на x86 (с выключенным флагом выравнивания) вы бы волей-неволей обратились к памяти. Изменив вашу программу так, чтобы все структуры были правильно выровнены (для не-x86 процессоров), вы также заметите, что ваша программа после этого на x86 станет выполняться быстрее, потому что x86 быстрее обращается к выровненным данным.
Другое, что так часто не дает людям жить — это порядок следования байт, прямой (big-endian) или обратный (little-endian). (Кому интересна этимология этих терминов, загляните в английский оригинал «Путешествий Гулливера» Джонатана Свифта :-) — прим. ред.). У процессора x86 возможен только один порядок следования байт, и он обратный. Процессоры MIPS и PPC допускают оба порядка следования байт, т. е. могут работать как с прямым, так и с обратным. Кроме того, процессоры MIPS и PPC являются процессорами типа RISC (с сокращенным набором команд), что означает, что некоторые операции типа
Существующие версии QNX4 работают только на однопроцессорных системах, в то время как QNX/Neutrino уже на момент публикации первого издания этой книги обеспечивала поддержку SMP по меньшей мере на архитектуре x86. SMP дает значительные преимущества, особенно в многопоточной ОС, но это одновременно и гораздо более серьезный пистолет для простреливания ноги (кто любопытен, поищите в Интернет по ключевой фразе «shoot yourself in the foot» — прим. ред.).
Например, в однопроцессорной машине обработчик прерывания (ISR) может вытеснить поток, но наоборот никогда не бывает. В однопроцессорной машине бывает полезно представить себе, что потоки якобы выполняются одновременно, хотя в действительности это не так.
В блоке SMP поток и обработчик прерывания могут работать одновременно, да и несколько потоков тоже могут работать одновременно. Так что SMP — это не только превосходная рабочая станция, но и неплохое средство тестирования программного обеспечения — если вы сделали какие бы то ни было «плохие» предположения о защите в многопоточной среде, в SMP-системе они однажды обязательно выплывут.
Философия переноса программ
Давайте теперь взглянем на все «сверху». Здесь мы рассмотрим:
• обмен сообщениями и систему «клиент/сервер»;
• обработчики прерываний (ISR).
Анализ обмена сообщениями
В QNX4 клиент мог найти сервер двумя способами:
• используя глобальное пространство имен;
• выполнение open в отношении администратора ввода/вывода.
Если взаимоотношения «клиент/сервер, которые вы переносите, базируются на глобальном пространстве имен, тогда клиент использует:
qnx_name_locate