|
原本以为用freeRTos写一个无线组网协议,用的SI4463,单片机用的stm32l151。协议框架都写出来了,用的freeRTos的二值信号量做同步的。就是开两个线程一个负责接收,一个负责发送;在中断中释放信号量。这周开始调试,发现无线两端只能一个发一个收;收到数据后验证然后立即回复,但是这个回复死后收不到,然后就是上示波器了;示波器显示很明显有连续的几个接收中断,但是没一个能进的。模块只能进自己的发送完成中断(就是发送完的那中断能响应,pnnet_rout_send_TACK(0)后的中断)
u8_t pnnet_sender_task(void)
{
u8_t ret;
/*得到设备操作*/
pnnet_get_dev_control( );
/*转换角色至发送者*/
pnnet_anti_collison_changeto_sender( );
pnnet_status.work_state = PNNET_STATE_SHAKE_HANDS;
pnnet_status.work_busy = 1;
for(;;)
{
/*进入链接发起*/
pnnet_rout_send_TACK(0);
ret = sys_sem_wait(&pnnet_anti_col_tx_sem,200);
if(ret)
{
pnnet_status.tx_count++;
if(pnnet_status.tx_count==3)
{
/*无回应*/
goto txerr;
}
}
else
{
pnnet_status.tx_count = 0;
break;
}
}
/*锁存 地址*/
pnnet_anti_collison_lock_addr(pnnet_rout_get_sender_addr());
/*发送数据*/
pnnet_status.send_end = MAC_send_tx_desc(0);
for(;;)
{
ret = sys_sem_wait(&pnnet_anti_col_tx_sem,50);
if(ret)
{
/*重发*/
MAC_send_tx_desc(1);
pnnet_status.tx_count++;
if(pnnet_status.tx_count>3)
{
/*无回应*/
goto txerr;
}
}
else
{
if(pnnet_status.again)
{
/*重发*/
MAC_send_tx_desc(1);
}
else
{
if(pnnet_status.send_end)
{
/*最后一包*/
pnnet_status.work_state = PNNET_STATE_CLOSING;
pnnet_status.tx_count = 0;
break;
}
pnnet_status.send_end = MAC_send_tx_desc(0);
}
}
}
/*发送NACK*/
for(;;)
{
pnnet_rout_send_NACK( );
sys_sem_wait(&pnnet_anti_col_tx_sem,20);
pnnet_status.tx_count++;
if(pnnet_status.tx_count>3)
{
pnnet_status.tx_count = 0;
pnnet_status.work_state = PNNET_STATE_CLOSE_LINE;
break;
}
}
/*切换至命令通道*/
radio_phy_start_Rx(RADIO_CMD_CHANNEL);
/*等待500ms*/
ret = sys_sem_wait(&pnnet_anti_col_tx_sem,500);
if(ret)
{
/*无回应*/
goto txerr;
}
else
{
/*发送完毕*/
/*释放发送完毕信号*/
pnnet_anti_collison_unLock_addr( );
/*切换至接受者*/
pnnet_anti_collison_changeto_reciver();
/*释放mac*/
MAC_release_TxDesc();
/*释放设备控制*/
pnnet_release_dev_control( );
return 0;
}
txerr:
/*切换至接受者*/
pnnet_anti_collison_changeto_reciver();
/*释放设备控制*/
pnnet_release_dev_control( );
/*返回通信失败*/
return 1;
}
在发送完成中断中,把无线模块切换成接收态,从此系统无法接收中断了。
上边程序中,ret = sys_sem_wait(&pnnet_anti_col_tx_sem,200);是200ms后不能接收到回复将连续发送3次TACK信号;系统只能响应三次发送完成中断。但是第另一个模块的回复其实已经收到了,只是系统没有响应。
进入sys_sem_wait
u8_t sys_sem_wait(sys_sem_t *sem, u32_t timeout)
{
BaseType_t ret;
ret = osSemaphoreWait(*sem,timeout);
if(ret == osOK)
{
return 0;
}
else
{
return 1;
}
}
系统调用了osSemaphoreWait即xSemaphoreTake,在xSemaphoreTake里有一段
for( ;; )
{
taskENTER_CRITICAL();
.....
taskEXIT_CRITICAL();
}
我不知道是不是taskENTER_CRITICAL();影响了我的中断响应。 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|