关于3100的消息机制
hi,
以MSP430FR5739和cc3100为例,MSP430是通过SPI发送指令的方式告诉cc3100他的读写动作,但是,MSP430这侧并非通过SPI中断信号来接收来自cc3100的数据,请问,MSP430如何实现通过SPI,实现对来自cc3100的数据的接收的 ?
请ti的专家以下面的socket中的recv函数为例解释一下这个机制。特别解释下这个机制和如下的代码中的
status = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvCmdCtrl, &Msg, &CmdExt);
中的Msg是什么关系,Msg带回来了什么 ?
谢谢。
int sl_Recv(int sd, void *pBuf, int Len, int flags) { _SlRecvMsg_u Msg; _SlCmdExt_t CmdExt; _SlReturnVal_t status; CmdExt.TxPayloadLen = 0; CmdExt.RxPayloadLen = Len; CmdExt.pTxPayload = NULL; CmdExt.pRxPayload = (UINT8 *)pBuf; Msg.Cmd.sd = sd; Msg.Cmd.StatusOrLen = Len; /* no size truncation in recv path */ CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen; Msg.Cmd.FamilyAndFlags = flags & 0x0F; status = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvCmdCtrl, &Msg, &CmdExt); if( status != SL_OS_RET_CODE_OK ) { return status; } /* if the Device side sends less than expected it is not the Driver's role */ /* the returned value could be smaller than the requested size */ return (int)Msg.Rsp.statusOrLen; }
就是用标准的SPI通信模式,你可以参考一下http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
我用的是CC3000,不过我看了下CC3100的api手册消息机制应该一样的。
我觉得CC3000的通讯机制是个限制,recv必须要轮询即使是使用select也是轮询。CC3000的所谓的recv或select超时。在单线程中就是卡在while里走了(设置1秒超时就是在while卡1秒,)。
hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen) { unsigned char *pucReceivedData, ucArgsize; unsigned short usLength; unsigned char *pucReceivedParams; unsigned short usReceivedEventOpcode = 0; unsigned long retValue32; unsigned char * RecvParams; unsigned char *RetParams; while (1)
就是上面函数里的while。
单线程时卡在while我还能理解。可以多线程呢。网上下了一个CC3000SDK\CC3000 SDK\LM4F120H5QR\Multithreaded WiFi Application\Multithreaded WiFi Source\Source\Multithreaded WiFi Application的例子。
以为会是挂起,原来也不是,它是在系统中开了一个优先级较低的线程做select。select还是卡在while里。
你可能也觉得这样没什么问题。
记住多线程为了解决CC3000的共享问题,在每个api里是要上锁的,这也是正确的,因为毕竟通讯时spi不能共享不然数据就错误了。看下面的情形:
假设我有两个线程一个select。一个是采集程序。select线程里处理接收的命令,采集程序上报数据。select优先级低,超时1秒。
每次上报时假如刚好select刚刚开始执行select函数,那你这次上报时间就要等待1秒,因为要等待锁释放。一般的socket中是不会存在这种问题。
归根到底是recv事件没有主动上报而是要轮询。比如lwip驱动DM9000,在recv设置超时1秒时是会挂起的cpu可以去做别的事情,也不会锁住DM9000到超时1秒,这recv超时等待期间你是可以发数据的。而CC3000就不行。这是我的理解,这算是CC3000的限制吧。