您的位置:控制工程论坛网论坛 » 软件与程序 » 软件编程经典培训实例 5、正确使用逻辑与&&、屏蔽&操作符

xilinxue

xilinxue   |   当前状态:在线

总积分:16186  2024年可用积分:0

注册时间: 2008-06-26

最后登录时间: 2020-03-22

空间 发短消息加为好友

软件编程经典培训实例 5、正确使用逻辑与&&、屏蔽&操作符

xilinxue  发表于 2008/11/6 12:54:03      836 查看 1 回复  [上一主题]  [下一主题]

手机阅读


【案例描述】:由于C语言中位与比求模效率高,因而系统设计时,对于模128的地方都改为与127,系统定义的宏为#define MOD128  127和#define W_MOD    127(定义的宏的名字易引起误解),但实际程序中还是采取求模,从而引起发送窗口欲重发的和实际重发的不一致,最终导致链路复位此类严重问题,曾在定位此问题时花了不少时间。

【处理过程】:处理过程如下:
#define     MOD128          127  //队列长128,当队头到128时,上其返回。
#define    W_MOD           127 //发送窗口队列,意义同上。
在函数L2_TO_L1()中,有如下语句:
        linkstate_ptr->SendWin.head = (head + 1) % W_MOD ;
这里当head=126时,SendWin.head = 0,这将造成发送窗口指针和队列窗口指针错位,造成链路复位;
另外,在重发函数void INVOKE_RETRANSMISSION(_US logic_link,_US n_r)中,有如下语句:
        retran_num = (LinkState[logic_link].Vs + MOD128  - (_UC)n_r) %  MOD128 ;
        w_head = (LinkState[logic_link].SendWin.head + W_MOD  - retran_num) % W_MOD ;
第一个语句求欲重发的消息包个数,第二个语句求重发的起始位置,当Vs小于n_r时,将造成实际重发数小于欲重发数,同时造成实际起始重发位置和欲重发起始位置错开,从而引起链路复位。上面三个语句应该做如下改动:
        linkstate_ptr->SendWin.head = (head + 1) & W_MOD ;

        retran_num = (LinkState[logic_link].Vs + MOD128  + 1 - (_UC)n_r) &  MOD128 ;
        w_head = (LinkState[logic_link].SendWin.head + W_MOD + 1 - retran_num) & W_MOD ;

1楼 0 0 回复
  • xilinxue

    xilinxue   |   当前状态:在线

    总积分:16186  2024年可用积分:0

    注册时间: 2008-06-26

    最后登录时间: 2020-03-22

    空间 发短消息加为好友

    xilinxue   发表于 2008/11/6 12:54:03

    【结  论】:由于链路通信对系统效率要求很高,算法采用效率最高的,但位与(&)和求模(%)这小小的区别,造成的竟是链路复位这种严重的错误。


    【思考与启示】:对这类问题,大家在阅读代码或代码审查时一定要注意,仔细一点往往能发现问题,但在测试中来定位这种问题,花费的时间往往更长。


     

    2楼 回复本楼

    引用 xilinxue 2008/11/6 12:54:03 发表于2楼的内容

总共 , 当前 /