1、在有OSSemPend(sys_global, 0, &perr),请求信号量的任务中,不需要含有OSTimeDlyHMSM(0,0,0,5)含有系统延时函数,她始终属于就绪状态,只要信号量为1则进入。 2、消息队列创建的消息队列一定要和定义的存取buf的长度保持一致,不然会导致设备重启。 mian()中创建:canqsq = OSQCreate (CANQSQ_BUF, 5); can.h:CAN_EXT OS_EVENT *canqsq; can.c: void cansnd_process(void * arg) { INT8U perr; void *mss; // struct pbuf* buf; for(;;) { mss = OSQPend(canqsq, 0, &perr); //得到需要发送数据的首地址 if(mss != NULL) //确实有数据 { // Key_down_pa_count_i++; if(TrainLink != LINK) { can1_send(mss); } else { can2_send(mss); } } OSTimeDlyHMSM(0, 0,0,200); // 数据发送间隔至少200ms } } 其他函数或任务中发送: /* * dst_dev 目标设备 * dev_no 目标设备序号 * Cmd 数据包的主要功能 * state 设置设备状态 *注:CAN中的协议设置和网络中的一致,只不过位不匹配 */ void SendToCan(struct sys_dev *pcu_cur, u8 Cmd) { INT8U perr; bool State = TRUE; // struct stru_sndcan *SND_CAN = OSMemGet (lantxbuf, &perr);//申请一块内存 10.29,此处不需要申请内存发送,浪费 struct stru_can *SND_CAN = (struct stru_can*)snd_can; if(SND_CAN == NULL) { return; } // memset(SND_CAN,0,32); if(SND_CAN != NULL) { if(TrainLink != LINK) { SND_CAN->RecDev = pcu_cur->dev_type; //帧头 接收设备类型 07174 SND_CAN->SndDevIP = LocalAddr; //发送设备ip,此处没用到,暂时未0x30 SND_CAN->CmdTyp = Cmd & 0x0F; //命令类型,在网络中是0x36,但因为这里只有5个bit,所以用06代替 SND_CAN->SndTraNum = pcu_cur->dev_train_num; //接收设备号 SND_CAN->FrameHead = 0xFF; //数据帧帧头 SND_CAN->RecDevIP = pcu_cur->dev_addr; //pcu_cur->dev_addr接收设备ip SND_CAN->SndDev = Dev_DACU; //发送设备类型 SND_CAN->Analog = DIGIT; //数字,ANALOG模拟 ANALOG if((0 == net_state)||(ANALOG == pis_state)) { // || (ANALOG == pis_state)//&& ((DIGIT == pis_state) || (tiu->dev_active == established)) SND_CAN->Analog = ANALOG; //数字,模拟DIGIT ANALOG } else if((1 == net_state) && ((DIGIT == pis_state)||(FREE == pis_state))) { // 网络通+数字对讲请求或者口播开通 SND_CAN->Analog = DIGIT; //数字,模拟DIGIT ANALOG } switch (pcu_cur->dev_type) //根据接收设备来判断 { case Dev_SBCU: if(pcu_cur->dev_active == shutdown) { SND_CAN->Action = IntercomEnd;//状态 与命令配合 广播开始或结束 } else if(pcu_cur->dev_active == established) { SND_CAN->Action = IntercomStart; } else if(pcu_cur->dev_active == waitting) //CCU 对CCU请求对讲 { SND_CAN->RecDev = Dev_DACU_Group; //接收设备 // SND_CAN[5] = 0x30; SND_CAN->Action = IntercomRequest;//状态 与命令配合 广播开始或结束 } SND_CAN->Channel = pcu_cur->dev_channel; //一个PCU上有两个报警装置 break; case Dev_DACU: if(pcu_cur->dev_active == shutdown) //司机对讲,请求挂断+应答停止 { SND_CAN->Action = IntercomEnd;//状态 与命令配合 广播开始或结束 } else if(pcu_cur->dev_active == established) //司机对讲,请求呼叫 { // SND_CAN->Action = IntercomStart; SND_CAN->RecDev = Dev_DACU_Group; //接收设备 // SND_CAN[5] = 0x30; SND_CAN->Action = IntercomRequest;//状态 与命令配合 广播开始或结束 } else if(pcu_cur->dev_active == waitting) //CCU 对CCU请求对讲 { SND_CAN->RecDev = Dev_DACU_Group; //接收设备 // SND_CAN[5] = 0x30; SND_CAN->Action = IntercomRequest;//状态 与命令配合 广播开始或结束 } SND_CAN->Channel = pcu_cur->dev_channel; //一个PCU上有两个报警装置 break; case Dev_CBCU_Group: if(pcu_cur->dev_active == shutdown) { SND_CAN->Action = CCUBoardcastEnd; } else if(pcu_cur->dev_active == established) { SND_CAN->Action = CCUBoardcastStart; } SND_CAN->Channel = 0x01; break; default: State = FALSE; break; } if (Boardcast == Cmd) { SND_CAN->Channel = PRIO.ca_prio; //如果是口播,则告诉口播的优先级PRIO.cur_prio } } else { switch (pcu_cur->dev_type) //根据接收设备来判断 { case Dev_SBCU: if(pcu_cur->dev_active == shutdown) { // SND_CAN->Action = IntercomEnd;//状态 与命令配合 广播开始或结束 SND_CAN->FrameHead = 0x09; //广播停止 } else if(pcu_cur->dev_active == established) { // SND_CAN->Action = IntercomStart; } else if(pcu_cur->dev_active == waitting) //CCU 对CCU请求对讲 { // SND_CAN->RecDev = Dev_DACU_Group; //接收设备 // SND_CAN->Action = IntercomRequest;//状态 与命令配合 广播开始或结束 SND_CAN->FrameHead = 0x08; //广播发送 } SND_CAN->Channel = pcu_cur->dev_channel; //一个PCU上有两个报警装置 break; case Dev_DACU: if(pcu_cur->dev_active == shutdown) //司机对讲,请求挂断+应答停止 { // SND_CAN->Action = IntercomEnd;//状态 与命令配合 广播开始或结束 SND_CAN->FrameHead = 0x05; //司机对讲关闭 } else if(pcu_cur->dev_active == established) //司机对讲,请求呼叫 { // SND_CAN->RecDev = Dev_DACU_Group; //接收设备 // SND_CAN->Action = IntercomRequest;//状态 与命令配合 广播开始或结束 SND_CAN->FrameHead = 0x04; //司机对讲接通 } else if(pcu_cur->dev_active == waitting) //CCU 对CCU请求对讲 { // SND_CAN->RecDev = Dev_DACU_Group; //接收设备 // SND_CAN->Action = IntercomRequest;//状态 与命令配合 广播开始或结束 SND_CAN->FrameHead = 0x04; //司机对讲接通 } SND_CAN->Channel = pcu_cur->dev_channel; //一个PCU上有两个报警装置 break; case Dev_CBCU_Group: if(pcu_cur->dev_active == shutdown) { // SND_CAN->Action = CCUBoardcastEnd; SND_CAN->FrameHead = 0x09; //广播停止 } else if(pcu_cur->dev_active == established) { // SND_CAN->Action = CCUBoardcastStart; SND_CAN->FrameHead = 0x08; //广播发送 } SND_CAN->Channel = 0x01; break; default: State = FALSE; break; } if(SND_CAN->FrameHead == 0x08) { SND_CAN->RecDev = 0x7E; //帧头 SND_CAN->SndDevIP = 0x04; //帧头 SND_CAN->CmdTyp = 0x04; //帧头 // SND_CAN->SndTraNum = 0x01; //帧头 SND_CAN->SndTraNum = 0x02; //口播:2,自动广播/紧急广播/OCC等其他:1;目前连挂仅口播 // SND_CAN->FrameHead = 0x08; //广播发送/停止 // SND_CAN->RecDevIP = 0x0D; //帧头 // SND_CAN->RecDevIP = SND_CAN->CmdTyp + SND_CAN->SndTraNum + SND_CAN->Channel + SND_CAN->FrameHead; //校验和 SND_CAN->RecDevIP = 0x02; //数据位 SND_CAN->SndDev = SND_CAN->CmdTyp + SND_CAN->SndTraNum + SND_CAN->FrameHead + SND_CAN->RecDevIP; //校验和 } else { SND_CAN->RecDev = 0x7E; //帧头 SND_CAN->SndDevIP = 0x03; //帧头 SND_CAN->CmdTyp = 0x04; //帧头 // SND_CAN->SndTraNum = 0x01; //帧头 SND_CAN->SndTraNum = 0x02; //口播:2,自动广播/紧急广播/OCC等其他:1;目前连挂仅口播 // SND_CAN->FrameHead = 0x08; //广播发送/停止 // SND_CAN->RecDevIP = 0x0D; //帧头 SND_CAN->RecDevIP = SND_CAN->CmdTyp + SND_CAN->SndTraNum + SND_CAN->FrameHead; //校验和 } } } else { State = FALSE; } if(State == TRUE ) { SND_CAN->PaType = pa_type_wh; SND_CAN->FrameEnd = 0xFE; //结尾 OSQPost (canqsq, SND_CAN); //给网络发送进程一组数据,让lansnd_process()开始工作 } }
|
|