最近在开发一个基于spi的双机通讯协议。协议约定:主从按照固定帧发送和接收数据,所以使用Linux 消息队列的机制进行数据传递和简单的过滤功能更为方便。但是在写daemon的时候,运行居然报出“Function not implemented”,可以猜测,我拿到的Android版本是把msgq干掉了。
1,打开消息队列
在kernel的deconfig配置文件中修改:
CONFIG_SYSVIPC=y
2,daemon启动使用msgq需要的selinux权限:
修改:system / sepolicy/public/domain.te
neverallow * *:{ shm sem msg msgq } *;改为:neverallow * *:{ shm sem } *;
在daemon对应的te文件中加入:
allow spitest spitest:msgq {create destroy getattr setattr read write associate unix_read unix_write enqueue};
allow spitest spitest:msg {send receive};
3,daemon的结构
daemon在系统的中的角色是一个服务器。
创建了四个线程,main:负责socket并发接收来自多个客户端的数据,放到发送队列里。
report:负责socket发送接收队列里面所有的数据到所有的客户端。
spi thread:负责发送接收spi数据,并放到两个队列里。
input:负责接收单片机中断信号,收到信号后,会往接收队列发空包,用于接收单片机传过来的数据。
4.实例:
以spi thread为例:
void *spi_thread(void *write_fd) {
int msgtx = -1;
int msgrx = -1;
int ret ;
msg_st rcv,snd;
rcv.type = 5 ;
snd.type = 5 ;
key_t key = ftok("/data",'6');
key_t key1 = ftok("/data",'7');
msgtx = msgget(key, 0666 | IPC_CREAT);
printf("errno = %s\n", strerror(errno));
if(-1 == msgtx )
{
printf("msgget failed with error\n");
exit(1);
}
msgrx = msgget(key1, 0666 | IPC_CREAT);
printf("errno = %s\n", strerror(errno));
if(-1 == msgrx )
{
printf("msgget failed with error\n");
exit(1);
}
while(1)
{
memset(&rcv.data, 0, 20);
memset(&snd.data, 0, 20);
ret = msgrcv(msgtx,&rcv,sizeof(rcv)-sizeof(rcv.type),rcv.type,0);
if(ret > 0){
printf("spi_thread snd.data[0] = 0x%x,snd.data[1]= 0x%x,snd.data[2]= 0x%x\n",rcv.data[0],rcv.data[1],rcv.data[2]);
mpu_sync_one(spi_fd,(MM_Comm_str *)rcv.data,(MM_Comm_str *)snd.data);
//if(rcv.data[1]==0x99)
msgsnd(msgrx,&snd,sizeof(snd)-sizeof(snd.type),IPC_NOWAIT);
}
}
return NULL;
}