Исследования пульсов и сообщений. Настройка IDE Momentix для наблюдения за целевой платформой. Исследование обмена сообщениями и импульсами с помощью IDE Momentix

Страницы работы

Фрагмент текста работы

Пример 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). Сервер разблокируется, отвечает клиенту, и клиент переходит в сотояние

Похожие материалы

Информация о работе