Пример 1 исследования пульсов и сообщений
1. Цель исследования
Настройка IDE Momentix для наблюдения за целевой платформой. Исследование обмена сообщениями и импульсами с помощью IDE Momentix.
2. План работы
§ Исследование обмена сообщениями QNX
§ Исследование обмена импульсами QNX
§ Исследование обмена сообщениями POSIX
3. Теоретические сведения
В данном примере рассматривается реализация обмена сообщениями в «клиент-серверном» приложении. При этом сервер и клиент сменяют свои состояния. Когда сервер ждет сообщения, он находится в состоянии блокировки по приему (RECEIVE). По получении сообщения сервер переходит в состояние готовности (READY). (рис.2.1)
Рис.2.1. Смена состояний сервера
При передаче сообщения клиент переключается из состояния готовности (READY) в состояние либо блокировки по передачи(SEND), либо блокировки по приему (REPLY), в зависимости от того, в каком состоянии находится сервер.
Рис.2.2. Смена состояний клиента
Импульсы – механизм отправки коротких сообщений без блокировки клиента.
4. Исследование обмена сообщениями QNX
4.1 . Используемые функции
Сервер:
#include <sys/neutrino.h>
int ChannelCreate(unsigned flags) - создание канала для передачи сообщения. Возвращает номер канала.
int MsgReceive(int chid, // идентификатор канала
void * msg, // указатель на буфер для приема сообщения
int bytes, // его размер
struct _msg_info * info ) // структура с информацией о сообщении
- прием сообщения. Возвращает 0, если получен импульс, и положительное значение, если получено сообщение.
int MsgReply( int rcvid, // идентификатор отправителя
int status, // код (EOK – успешное завершение)
const void* msg, // указатель на передаваемое сообщение
int size ) // его размер
– ответ на сообщение.
Клиент:
int ConnectAttach(uint32_t nd, // дескриптор узла (0 – на локальном)
pid_t pid, // идентификатор процесса
int chid, // идентификатор канала
unsigned index,
int flags )
– создание соединения для передачи сообщения. Возвращает идентификатор соединения.
int MsgSend( int coid, // идентификатор соединения
const void* smsg, // указатель на передаваемое сообщение
int sbytes, // его размер
void* rmsg, // указатель на буфер ответного сообщения
int rbytes ) // его размер
– отправка сообщения и блокирование клиента до получения ответа от сервера.
int ConnectDetach( int coid // идентификатор соединения
)
- разрыв соединения.
4.2 . Структура клиент-серверного приложения
Рис.4.1. Функциональная структура клиента
Рис.4.2. Функциональная структура cервера
4.3 . Листинги исходных кодов
Листинг 4.1. _msg_client.c
#include <stdlib.h>
#include <stdio.h>
#include <sys/neutrino.h>
#include <unistd.h>
#define PROGNAME "_msg_client: "
#define PROCID 3055647
int main(int argc, char *argv[]) {
char *smsg = "HELLO! IT IS CLIENT"; // A pointer to a buffer that contains the message that we want to send
char *rmsg [ 512 ]; // A pointer to a buffer where the reply can be stored
int coid; // The ID of the channel to send the message on
int ret; // Returned value, for checking errors
sleep(1);
// Establish a connection between a process and a channel
coid = ConnectAttach ( 0, // The node descriptor of the node on which the process that owns the channel is running
PROCID, // The process ID of the owner of the channel.
1, // The channel ID of the channel to connect to the process.
0, // The lowest acceptable connection ID
0 ); // flags
if( coid == -1 ){
perror( PROGNAME "ConnectAttach" );
exit( EXIT_FAILURE );
}
// Send a message to a channel
ret = MsgSend( coid, // The ID of the channel to send the message on
smsg, // A pointer to a buffer that contains the message that we want to send.
strlen( smsg )+ 1, // The number of bytes to send
rmsg, // A pointer to a buffer where the reply can be stored
sizeof( rmsg )); // The size of the reply buffer, in bytes
if( ret == -1 ){
perror( PROGNAME "MsgSend" );
exit( EXIT_FAILURE );
}
if( strlen( rmsg ) > 0 ) {
printf ( "Process with ID = %d replied %s \n", PROCID, rmsg );
}
// Break a connection between a process and a channel
ConnectDetach( coid );
return EXIT_SUCCESS;}
Листинг 4.2. _msg_server.c
#include <stdlib.h>
#include <stdio.h>
#include <sys/neutrino.h>
#include <errno.h>
int main(int argc, char *argv[]) {
int rcvid; // for returns value
int chid; // The ID of a channel that we established by calling ChannelCreate()
char *msg [ 512 ];// A pointer to a buffer where the function can store the received data
// Create a communications channel
chid = ChannelCreate(0 );
while ( 1 ){
// Wait for a message or pulse on a channel
rcvid = MsgReceive( chid, // The ID of a channel that we established by calling ChannelCreate()
msg, // A pointer to a buffer where the function can store the received data
sizeof( msg ),// The size of the buffer
NULL );
printf ( "Receive message,rcvid = %d \n ", rcvid );
printf ( "Message: %s \n", msg );
// Reply with a message
strcpy ( msg,"HELLO! IT IS SERVER\n");
MsgReply( rcvid, // The receive ID that MsgReceive*() returned when we received the message.
EOK, // The status to use when unblocking the MsgSend*() call in the rcvid thread
msg, // A pointer to a buffer that contains the message that we want to reply with.
strlen (msg )+ 1);// The size of the message, in bytes
}
return EXIT_SUCCESS;}
4.4 Настройка IDE Momentics
Создаем проект. После выполнения «Build all» запускаем «Run…».
Получаем окно, показанное на рис.2.3.
Рис.2.3. Окно настройки запуска приложения
Выбираем приложение для запуска (рис.2.4) Рис.2.4. Выбор программы
Выбираем целевую платформу (рис.2.5).
Рис.2.5. Выбор целевой платформы
Рис.2.6. Настройки запуска
Для наблюдения за ходом работы используется QNX System Profiler. Для настройки на панели Target Navigator выбираем нужную целевую машину.
При нажатии правой кнопкой мыши выбираем kernel event trace -> log… И настраиваем:
4.5 . Результаты работы
Результаты работы:
Из представленного фрагмента следует, что изначально сервер находится в receive-блокированном состоянии, затем клиент посылает сообщение, и переходит в состояние блокировки по приему (reply). Сервер разблокируется, отвечает клиенту, и клиент переходит в сотояние
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.