⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtsscom.c

📁 RTX是当前非常流行的RTX实时操作系统
💻 C
字号:
/*****************************************************************************
***   RTSSCOM.c -- source file (RTSS to Win32 Communication function calls)      ***
******************************************************************************
****                                                                      ****
****     Source file containing functions that allow the RTSS process       ****
****     to communicate with a Win32 application                           ****  
****                                                                      ****
****     Last revision date:  1/4/99                                     ****
****     Programmer:  Dan Block                                           ****
****                                                                      ****
*****************************************************************************/
#include <windows.h>
#include <stdio.h>
#include <rtapi.h>
#include "cslrtx.h"
#include "rtsscom.h"

// global variables using by the following functions
HANDLE	g_hMutex,g_hShm,g_hSemPostC;
HANDLE	g_hSemPostCAck,g_hSemDRdy,g_hSemDRdyAck,g_hSemRecv;
HANDLE  g_hEvent,g_hSemAckEvent;
PSHRMEM	g_pshrcommand;
int g_EventCommand;
int g_SendEvent = 0;
long int g_mod_count,g_data_count,g_once_through;
float g_data[8][NUM_POINTS];

/*****************************************************************************
****   InitRTSS_Communication -- Sets up the communicatoin objects needed  **
****                             to communicate with a Win32 application    **
*****************************************************************************/
int InitRTSS_Communication(void) {
	
	// Open Shared Memory
	g_hShm = RtOpenSharedMemory( PAGE_READWRITE, FALSE, COECSL_SHM1, (LPVOID) &g_pshrcommand);
	if (g_hShm==0)
	{
		RtCloseHandle( g_hShm);
		printf("ERROR: Could not Open SharedMemory\n");
		return 1;
	}

	// Open Mutex
	g_hMutex = RtOpenMutex( SYNCHRONIZE, FALSE, COECSL_MUTEX);
	if (g_hMutex==0) {
		RtCloseHandle( g_hShm);
		RtCloseHandle(g_hMutex);
		printf("ERROR: Could not Open Mutex\n");
		return 1;
	}

	// Open Post Command Semaphore
	g_hSemPostC = RtOpenSemaphore( SYNCHRONIZE, FALSE, COECSL_SEM_COM_CLIENT);
	if (g_hSemPostC==0)
	{
		RtCloseHandle( g_hShm);
		RtCloseHandle( g_hMutex);
		RtCloseHandle( g_hSemPostC);
		printf("ERROR: Could not Open g_hSemPostC\n");
		return 1;
	}

	// Open Post Command Acknowledge Semaphore
	g_hSemPostCAck = RtOpenSemaphore( SYNCHRONIZE, FALSE, COECSL_SEM_COM_CLIENT_ACK);
	if (g_hSemPostCAck==0)
	{
		RtCloseHandle( g_hShm);
		RtCloseHandle( g_hMutex);
		RtCloseHandle( g_hSemPostC);
		RtCloseHandle( g_hSemPostCAck);
		printf("ERROR: Could not Open g_hSemPostCAck\n");
		return 1;
	}
	// Open Data Ready Semaphore
	g_hSemDRdy = RtOpenSemaphore( SYNCHRONIZE, FALSE, COECSL_SEM_DATA_RDY_SERVER);
	if (g_hSemDRdy==0)
	{
		RtCloseHandle( g_hShm);
		RtCloseHandle( g_hMutex);
		RtCloseHandle( g_hSemPostC);
		RtCloseHandle( g_hSemPostCAck);
		RtCloseHandle( g_hSemDRdy);
		printf("ERROR: Could not Open g_hSemDRdy\n");
		return 1;
	}
	// Open Data Ready Acknowledge Semaphore
	g_hSemDRdyAck = RtOpenSemaphore( SYNCHRONIZE, FALSE, COECSL_SEM_DATA_RDY_SERVER_ACK);
	if (g_hSemDRdyAck==0)
	{
		RtCloseHandle( g_hShm);
		RtCloseHandle( g_hMutex);
		RtCloseHandle( g_hSemPostC);
		RtCloseHandle( g_hSemPostCAck);
		RtCloseHandle( g_hSemDRdy);
		RtCloseHandle( g_hSemDRdyAck);
		printf("ERROR: Could not Open g_hSemDRdyAck\n");
		return 1;
	}
	// Open Receive Data Semaphore
	g_hSemRecv = RtOpenSemaphore( SYNCHRONIZE, FALSE, COECSL_SEM_DATA_RECV_CLIENT);
	if (g_hSemRecv==0)
	{
		RtCloseHandle( g_hShm);
		RtCloseHandle( g_hMutex);
		RtCloseHandle( g_hSemPostC);
		RtCloseHandle( g_hSemPostCAck);
		RtCloseHandle( g_hSemDRdy);
		RtCloseHandle( g_hSemDRdyAck);
		RtCloseHandle( g_hSemRecv);
		printf("ERROR: Could not Open g_hSemRecv\n");
		return 1;
	}
	// Open Acknowledge Event Semaphore
	g_hSemAckEvent = RtOpenSemaphore( SYNCHRONIZE, FALSE, COECSL_SEM_ACK_SENT_EVENT);
	if (g_hSemAckEvent==0)
	{
		RtCloseHandle( g_hShm);
		RtCloseHandle( g_hMutex);
		RtCloseHandle( g_hSemPostC);
		RtCloseHandle( g_hSemPostCAck);
		RtCloseHandle( g_hSemDRdy);
		RtCloseHandle( g_hSemDRdyAck);
		RtCloseHandle( g_hSemRecv);
		RtCloseHandle( g_hSemAckEvent);
		printf("ERROR: Could not Open g_hSemAckEvent\n");
		return 1;
	}
	// Open Event
	g_hEvent = RtOpenEvent( SYNCHRONIZE, FALSE, COECSL_EVENT1);
	if (g_hEvent==0)
	{
		RtCloseHandle( g_hShm);
		RtCloseHandle( g_hMutex);
		RtCloseHandle( g_hSemPostC);
		RtCloseHandle( g_hSemPostCAck);
		RtCloseHandle( g_hSemDRdy);
		RtCloseHandle( g_hSemDRdyAck);
		RtCloseHandle( g_hSemRecv);
		RtCloseHandle( g_hSemAckEvent);
		RtCloseHandle( g_hEvent);
		printf("ERROR: Could not Open g_hEvent\n");
		return 1;
	}
// Wait to sync with DLL
	RtWaitForSingleObject(g_hMutex, INFINITE);

	return 0;
}

/*****************************************************************************
****   WaitforCommandandProcessEvents -- This function continually waits   ****
****          for the Post Command Semaphore to be activated.  When PostC has **
****          been activated the command is acknowledged with the PostCAck 
****          semaphore and the command value is returned.
****          This function also checks to see if a send event command has been
****          requested.  The parameter "eventcheckmillsec" determines how 
****          often a check is done to see if an event has been requested to be 
****          sent.  The minimum value is 1.   
*****************************************************************************/
LONG WaitforCommandandProcessEvents(DWORD eventcheckmillsec) {

	LONG command;

	// wait for the PostC semaphore
	while (RtWaitForSingleObject(g_hSemPostC, eventcheckmillsec) == WAIT_TIMEOUT) {
		    // check if there is an event send request
			if (g_SendEvent == 1) {
				g_pshrcommand->Event_Command = CSL_EVENT;
				g_pshrcommand->Event_UserCommand = g_EventCommand;
				g_SendEvent = 0;
				RtSetEvent(g_hEvent);
				RtWaitForSingleObject(g_hSemAckEvent, INFINITE);
			}

		}
		command = g_pshrcommand->Command_for_Client;
		// Acknowledge that comand was received
		RtReleaseSemaphore( g_hSemPostCAck, 1, NULL);

		return command;
}

// check the status of Event
int ProcessingEvent(void) {
	return g_SendEvent;
}

// Send an Event to the Win32 DLL
// The VB program will need to have code to process the eventcommand 
// number sent
void fcnSendEvent(int eventcommand) {

	if (g_SendEvent == 0) {
	    g_EventCommand = eventcommand;
        g_SendEvent = 1;
	}
}

/*****************************************************************************
****   GetSentData -- Call this function when a GetDataCommand has been sent **
****                  GetSentData returns in its parameters an array of 20 **
****                  floating point value and an array of characters. **
****                  Depending on what command was sent, your program should **
****                  know how to handle the sent data.
*****************************************************************************/
void GetSentData(float data[20],char *buffer) {

	int i;
	
	// get Sent float data from the shared memory
	for (i=0;i<20;i++) {
		data[i] = g_pshrcommand->Send_to_Client[i];
	}

	// get Sent char data and Null Terminator from the shared memory
	for (i=0;i<g_pshrcommand->bufferlength+1;i++) {
		buffer[i] = g_pshrcommand->buffer[i];
	}

	// acknowledge that data was received
	RtReleaseSemaphore( g_hSemRecv, 1, NULL);
}

/*****************************************************************************
****   SetSendData -- Call this function when a RecvDataCommand has been sent **
****                  SetSendData's parameter 'data' is a floating point array **
****                  of the values being sent to the Win32 Server DLL (mecha.dll) 
****                  Depending on the command sent the RTSS process should know **
****                  what data to send to the Win32 DLL
*****************************************************************************/
void SetSendData(float data[20]) {

	int i;

	// Load shared memory with data to be sent
	for (i=0;i<20;i++) {
		g_pshrcommand->Send_to_Server[i] = data[i];
	}
	// Set Semaphore Data Ready			
	RtReleaseSemaphore( g_hSemDRdy, 1, NULL);
	// Wait for acknowledgement that the data was received
	RtWaitForSingleObject(g_hSemDRdyAck, INFINITE);

}

/*********************************************************************
****   DeleteRTSS_Communcation -- Closes all communication objects **
*****************************************************************************/
void DeleteRTSS_Communication(void) {

	RtCloseHandle( g_hShm);
	RtCloseHandle( g_hMutex);
	RtCloseHandle( g_hSemPostC);
	RtCloseHandle( g_hSemPostCAck);
	RtCloseHandle( g_hSemDRdy);
	RtCloseHandle( g_hSemDRdyAck);
	RtCloseHandle( g_hSemRecv);
	RtCloseHandle( g_hSemAckEvent);
	RtCloseHandle( g_hEvent);
}

//  RTX 4.2's library does not have the standard 'sprintf' function
//  only the 'vsprintf' function so I had to create my one 'sprintf'
//  function.  You can read more about vsprintf in Visual C++'s 
//  On-line help  
void csl_sprintf( char *Buffer, const char *Format, ... ) {
	va_list ArgList;

	va_start(ArgList, Format);
	vsprintf(Buffer, Format, ArgList);
	va_end(ArgList);
}

// Initialize global variables for the savedata function
void init_savedata(void) {

	g_data_count = 0;
	g_mod_count = 0;
	g_once_through = 0;

}

/*****************************************************************************
****   savedata -- Stores data in a once through or circular buffer.
****               Call this function to save data points that can later be
****               written to a data file with the function 'savedatafile'.
****               If circ = 0 the buffer is once through.
****               If circ = 1 the buffer is circular
****               savedata can save 8 floating points values
*****************************************************************************/
void savedata(int circ,float d1,float d2,float d3,float d4,float d5,
              float d6,float d7,float d8)
{
	 // check if data_count larger the buffer size
     if (g_data_count < NUM_POINTS) {
		 // save data every POINT_INCREMENT calls to savedata
        if ((g_mod_count%POINT_INCREMENT)==0) {
			// g_data is the buffer
           g_data[0][g_data_count] = d1;
           g_data[1][g_data_count] = d2;
           g_data[2][g_data_count] = d3;
           g_data[3][g_data_count] = d4;
           g_data[4][g_data_count] = d5;
           g_data[5][g_data_count] = d6;
           g_data[6][g_data_count] = d7;
           g_data[7][g_data_count] = d8;
		   // keep track of data size and index
           g_data_count++;
           g_mod_count++;
        } else {
           g_mod_count++;
        }
     }
	 // If using as circular buffer reset index g_data_count back
	 // to zero when buffer is full
	 if ((g_data_count == NUM_POINTS) && (circ == 1)) {
           g_once_through = 1;
           g_mod_count = 0;
           g_data_count = 0;
     }

}

/*****************************************************************************
****   savedatafile -- Write data stored by the 'savedata' function
****                   to the filename given in datafile
*****************************************************************************/
int savedatafile(char* datafile) {

	HANDLE  hmyfile;
	char mybuff[256];
	DWORD mybyteswritten;
    int i;
	
	// open the file
	if ((hmyfile = CreateFile(datafile,GENERIC_WRITE,0,NULL,CREATE_ALWAYS
											,FILE_ATTRIBUTE_NORMAL
											,NULL)) == INVALID_HANDLE_VALUE) {
		printf("error opening file, error code %ld",GetLastError());
		return 1;
	}

	
	// write a header to the file User Matlab comment '%'
    csl_sprintf(mybuff,"%% var1 var2 var3 var4 var5 var6 var7 var8\n");
	if (WriteFile(hmyfile,mybuff,strlen(mybuff), &mybyteswritten,NULL) == 0) {
		printf("Error writing to file");
		CloseHandle(hmyfile);
		return 2;
	}
	// check if using a circular buffer 
	if (g_once_through == 1) {
		g_data_count = NUM_POINTS;
	}
	// write data to file
    for (i=0;i<g_data_count;i++) {
        csl_sprintf(mybuff,"%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n",
                                                          g_data[0][i],
                                                          g_data[1][i],
                                                          g_data[2][i],
                                                          g_data[3][i],
                                                          g_data[4][i],
                                                          g_data[5][i],
                                                          g_data[6][i],
                                                          g_data[7][i]
                                                          );
		WriteFile(hmyfile,mybuff,strlen(mybuff), &mybyteswritten,NULL);
    } /* endfor */

	// close file
    CloseHandle(hmyfile);

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -