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

📄 lipc.c

📁 基于嵌入式linux下
💻 C
字号:
/*********************************************************
	This is the source code file of application IPC.
**********************************************************
***/
#include "inc.h"
/***********************************************************
	The Init function is called by Proc when Proc starts,the 
system will assign a shared room for the proc.
	Every function returns a point to a buf which corresponds 
the struct of porc's state.
	par1 : key_t	PROCID_*
		The Key of the Proc you want access, 
	par2 : flag
		The flag shows if the memoy is Readonly.when called
	by outside proc,just for reading,flag value should use SHM_RDONLY;
	when by local proc for read and write,should use 0.
************************************************************
***/
const char *PROC_LOCKFILE[] = {"/tmp/GuardLock","/tmp/GPSLock","/tmp/FTPLock","/tmp/KeyBLock"
			,"/tmp/MediaLock","/tmp/Dispatchlock"};
static int	Fd_LOCKFILE[PROC_NUMBERS];
static void *SysShareMem[PROC_NUMBERS];
static int Sys_MsgqID;
int ReceiveMsgQ=1;

void *IPC_ProcState_Init(key_t key,int flag)				//For Guard_Proc
{
	void	*ptr;
	int		shmID,fd;
	size_t	ProcState_Size;

	//printf("Proc Key is %d!\r\n",key);
	SysShareMem[key] = NULL;
	switch (key)
	{
		case PROCID_GUARD :
			ProcState_Size = sizeof(Guard_Info);
			break;
		case PROCID_GPS :
			//printf("Init GPS proc!\r\n");
			ProcState_Size = sizeof(GPS_Info);
			break;
		case PROCID_FTP :
			ProcState_Size = sizeof(FTP_Info);
			break;
		case PROCID_KEYB :
			//printf("Init KEYB proc!\r\n");
			ProcState_Size = sizeof(KeyB_Info);
			break;
		case PROCID_MEDIA :
			//printf("Init media proc!\r\n");
			ProcState_Size = sizeof(Media_Info);
			break;
		case PROCID_DISPATCH :
			ProcState_Size = sizeof(Dispatch_Info);
			break;
		default:
			return NULL;
			break;
	}
	
	shmID = shmget(ROOT_SHAREMEM_KEY + key,ProcState_Size,IPC_CREAT | SHM_R | SHM_W);
	if (shmID < 0)
	{
		perror("share mem wrong!\r\n");
		printf("Keys is %08x,flag is %d!\r\n",ROOT_SHAREMEM_KEY+key,flag);
		return NULL;
	}
	if((ptr = shmat(shmID,0,flag)) == (void *) -1)
	{
		perror("share mem at wrong!\r\n");
		return NULL;
	}

//	if(!flag)		//by local proc init,will init a share mem lock too
	{
		if((fd = open(PROC_LOCKFILE[key],O_RDWR|O_CREAT,S_IRWXU)) < 0)
		{
			printf("fd is %d!\r\n",fd);
			printf("error!\r\n");
			return ;
		}
		if(write(fd,"1",1)<0)
		{
			printf("Lock file error!\r\n");
		}
		Fd_LOCKFILE[key] = fd;
	}
	SysShareMem[key] = ptr;
	return ptr;
}
int IPC_ProcState_Read(key_t key,void *pShareMem,void *pData)
{
	size_t	ProcState_Size;

	switch (key)
	{
		case PROCID_GUARD :
			ProcState_Size = sizeof(Guard_Info);
			break;
		case PROCID_GPS :
			ProcState_Size = sizeof(GPS_Info);
			break;
		case PROCID_FTP :
			ProcState_Size = sizeof(FTP_Info);
			break;
		case PROCID_KEYB :
			ProcState_Size = sizeof(KeyB_Info);
			break;
		case PROCID_MEDIA :
			ProcState_Size = sizeof(Media_Info);
			break;
		case PROCID_DISPATCH :
			ProcState_Size = sizeof(Dispatch_Info);
			break;
		default:
			return NULL;
			break;
	}
	if(LockFile(Fd_LOCKFILE[key],F_RDLCK)<0)
	{
		printf("Lock Failed!\r\n");
		return -1;
	}
	memcpy(pData,pShareMem,ProcState_Size);	//copy data to share mem
	if(LockFile(Fd_LOCKFILE[key],F_UNLCK)<0)
	{
		printf("UnLock Failed!\r\n");
		return -1;
	}
	return 0;
}
int IPC_ProcState_Write(key_t key,void *pShareMem,void *pData)
{
	size_t	ProcState_Size;

	switch (key)
	{
		case PROCID_GUARD :
			ProcState_Size = sizeof(Guard_Info);
			break;
		case PROCID_GPS :
			ProcState_Size = sizeof(GPS_Info);
			break;
		case PROCID_FTP :
			ProcState_Size = sizeof(FTP_Info);
			break;
		case PROCID_KEYB :
			ProcState_Size = sizeof(KeyB_Info);
			break;
		case PROCID_MEDIA :
			ProcState_Size = sizeof(Media_Info);
			break;
		case PROCID_DISPATCH :
			ProcState_Size = sizeof(Dispatch_Info);
			break;
		default:
			return NULL;
			break;
	}
	if(LockFile(Fd_LOCKFILE[key],F_WRLCK)<0)
	{
		printf("Lock Failed!\r\n");
		return -1;
	}
	memcpy(pShareMem,pData,ProcState_Size);	//copy data to share mem
	if(LockFile(Fd_LOCKFILE[key],F_UNLCK)<0)
	{
		printf("UnLock Failed!\r\n");
		return -1;
	}
	return 0;
}
/************************************************
	To Lock or unlock the Proc lock.
*************************************************
***/
int LockFile(int fd,int cmd)
{	
	struct flock lock;

	lock.l_type = cmd;
	lock.l_start = 0;
	lock.l_whence = 0;
	lock.l_len = 1;

	return(fcntl(fd,F_SETLKW,&lock));
}
/**************************************************
	MSGQ_Init function will return a msqid point
to the system's msg queue.
***************************************************
***/
int MSGQ_Init(void)
{
	Sys_MsgqID = msgget(MSG_QUEUE_KEY,IPC_CREAT);
	return Sys_MsgqID;
}
/**************************************************
	MSGQ_Init function will clear all the messages
to key proc.
***************************************************
***/
void MSGQ_Clear(key_t key)
{
	char tmpbuf[128];
	while(1)	//clear all msg still in buf
	{
		memset(tmpbuf,0,sizeof(tmpbuf));
		if(MSGQ_Read(key,tmpbuf)>0);
		else
			break;
	}
}
/**************************************************
	MSGQ_Init and IPC_ProcState_Init must be called
before this function.
	MSGQ_Init function will return a msqid point
to the system's msg queue.
	par1 : key_t	PROCID_*
		The Key of the Proc you want send msg to 
	par2 : data	
		the pointer to the data to be send
	par3 : datalen
		the data length ,should less than 128
	return value : the value which msgsnd returns
***************************************************
***/
int MSGQ_Send(key_t key,void *data,int datalen)
{
	Pid_Info *pinfo;
	pid_t	pid;
	AppMsg  lmsg;
	int retr;

	pinfo = (Pid_Info *)SysShareMem[key];
	if (pinfo==NULL)
		printf("Media Share mem NULL!\r\n");
	pid = pinfo->PID;

	if(pid==0)			//the dest proc not exit
		return -1;

	if(key==0)
		lmsg.DestProc = 255;
	else
		lmsg.DestProc = key;
	if(datalen>128)
		datalen=128;
	memcpy(lmsg.Data,data,datalen);

	retr = msgsnd(Sys_MsgqID,&lmsg,datalen,IPC_NOWAIT);
	kill(pid,SIGUSR1);
	return retr;
}
/**************************************************
	MSGQ_Init and IPC_ProcState_Init must be called
before this function.
	MSGQ_Init function will return a msqid point
to the system's msg queue.
	par1 : key_t	PROCID_*
		The Key of the Proc you want send msg to.
	par2 : data	
		the pointer to the buffer where the data
to be stored.
	return value:
		the readded data length
***************************************************
***/
int MSGQ_Read(key_t key,void *data)
{
	int retr;
	AppMsg  lmsg;

	if (key==0)
		key = 255;
	retr = msgrcv(Sys_MsgqID,&lmsg,sizeof(lmsg.Data),key,IPC_NOWAIT);
	if(retr>0)
		memcpy(data,lmsg.Data,retr);
	return retr;
}
void Sig_Handle(int signo)
{
	int		num;

	printf("sig %d received!\r\n",signo);
	switch(signo)
	{
		case SIGUSR1:
		case SIGUSR2:
//			printf("Catch sig USER!\r\n");
			ReceiveMsgQ = 1;
			break;
		case SIGKILL:
//			printf("Prog End!\r\n");
			break;
		default:
			break;
	}
}
void Signal_Init(void)
{
	if (signal(SIGUSR1,Sig_Handle) == SIG_ERR)
		perror("cann't catch SIGUSR1!\r\n");
	if (signal(SIGUSR2,Sig_Handle) == SIG_ERR)
		perror("cann't catch SIGUSR2!\r\n");
}

⌨️ 快捷键说明

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