/* * READ_CTF_SHM reads metainformation or selected blocks of data from * shared memory. This function can be used for real-time processing of * data while it is being acquired. * * Use as * [msgType msgId sampleNumber numSamples numChannels] = read_ctf_shm; * or * [data] = read_ctf_shm(msgNumber); * [data] = read_ctf_shm(msgNumber, numValues); * * Copyright (C) 2007, Robert Oostenveld * * $Id: read_ctf_shm.c 7123 2012-12-06 21:21:38Z roboos $ */ #include #include #include #include "mex.h" #include "matrix.h" #define ACQ_MSGQ_SIZE 600 #define ACQ_MSGQ_SHMKEY 0x39457f73 #define ACQ_MSGQ_SHMPROJID 12345 #define ACQ_MSGQ_SHMPATH "/opt/ctf/bin/Acq" typedef enum { ACQ_MSGQ_SETUP_COLLECTION, ACQ_MSGQ_DATA, ACQ_MSGQ_CLOSE_CONNECTION, ACQ_MSGQ_INVALID = INT_MAX } ACQ_MessageType; typedef struct { ACQ_MessageType message_type; int messageId; int sampleNumber; int numSamples; int numChannels; int data[28160]; } ACQ_MessagePacketType; void mexFunction (int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) { key_t key; ACQ_MessagePacketType *packet; int *msgType, *msgId, *sampleNumber, *numSamples, *numChannels; int shmid, shmsize, i; int numValues = 28160; shmsize = sizeof(ACQ_MessagePacketType) * ACQ_MSGQ_SIZE; /* make the key if ((key = ftok(ACQ_MSGQ_SHMPATH, ACQ_MSGQ_SHMPROJID)) == -1) { perror("ftok"); exit(1); } */ /* use the pre-defined key */ key = ACQ_MSGQ_SHMKEY; /* connect to (and possibly create) the segment */ if ((shmid = shmget(key, shmsize, 0644 | IPC_CREAT )) == -1) mexErrMsgTxt("shmget"); /* attach to the segment to get a pointer to it */ packet = shmat(shmid, (void *)0, 0); if ((char *)packet == (char *)(-1)) mexErrMsgTxt("shmat"); if (nrhs==0) { /* read the meta information from all packets */ plhs[0] = mxCreateNumericMatrix(1, ACQ_MSGQ_SIZE, mxINT32_CLASS, mxREAL); plhs[1] = mxCreateNumericMatrix(1, ACQ_MSGQ_SIZE, mxINT32_CLASS, mxREAL); plhs[2] = mxCreateNumericMatrix(1, ACQ_MSGQ_SIZE, mxINT32_CLASS, mxREAL); plhs[3] = mxCreateNumericMatrix(1, ACQ_MSGQ_SIZE, mxINT32_CLASS, mxREAL); plhs[4] = mxCreateNumericMatrix(1, ACQ_MSGQ_SIZE, mxINT32_CLASS, mxREAL); msgType = mxGetData(plhs[0]); msgId = mxGetData(plhs[1]); sampleNumber = mxGetData(plhs[2]); numSamples = mxGetData(plhs[3]); numChannels = mxGetData(plhs[4]); for (i=0; i28160 ? 28160 : numValues ); /* check boundary */ numValues = ( numValues<0 ? 0 : numValues ); /* check boundary */ } /* read the data from the selected packet */ /* one-offset in Matlab, zero-offset in C */ i = mxGetScalar(prhs[0]) - 1; if (i<0) mexErrMsgTxt("Cannot read before the first packet"); if (i>=ACQ_MSGQ_SIZE) mexErrMsgTxt("Cannot read after the last packet"); plhs[0] = mxCreateNumericMatrix(1, numValues, mxINT32_CLASS, mxREAL); memcpy(mxGetData(plhs[0]), packet[i].data, numValues*sizeof(int)); } /* detach from the segment */ if (shmdt(packet) == -1) mexErrMsgTxt("shmdt"); } /* end of mexFunction */