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()开始工作
}
}
联系客服