PROFIBUS DP从站开发 VPC3源程序分析---assign_aux_buf()函数

assign_aux_buf( UWORD PTR_ATTR pwLens, UBYTE bCount, UBYTE PTR_ATTR pbAssign, UWORD PTR_ATTR pwAuxLen )

 


//
/// 以下程序注释由成都地质学院霸王猫添加,引用时请尊重作者劳动成果,标明引用者来自成都地质学院霸王猫。
//


UWORD assign_aux_buf( UWORD PTR_ATTR *pwLens, UBYTE bCount, UBYTE PTR_ATTR *pbAssign, UWORD PTR_ATTR *pwAuxLen )


   原理:
	AUX1和AUX2两个寄存器用于暂存获得的配置和参数化数据(如果支持站地址改变,还应加入SSA数据),它们所需的长度要保证数据传输的完整性,
同时也应最大限度的节省空间。因此,在配置长度时对参数化报文和配置报文的 DU部分长度进行反复比较,将最小值赋给AUX1,最大值赋给AUX2。



   入口参数:
        (1)、*pwLens  = 指向存储有“参数化缓冲器长度”、“配置缓冲器长度”和“站地址缓冲器长度”数组的指针
	(2)、bCount   = pwLens数组有3个向量,即:参数缓冲器、配置缓冲器、站地址缓冲器。函数将根据这3个缓冲器来分配辅助缓冲器1和辅助缓冲器2。
	(3)、*pbAssign= 位指针数组。定义了如何将Aux_Buf 1和 2分配给控制缓冲器SSA_Buf, Prm_Buf, Cfg_Buf。
			  该指针参数最终在函数vpc3_buf_init()中会赋值给	R_Aux_Buf_Sel,用于指示如何将Aux_Buf 1和 2分配给控制缓冲器SSA_Buf, Prm_Buf, Cfg_Buf。

 				R_Aux_Buf_Sel = 地址2AH = 定义参数化报文、配置报文、站地址报文分别选择哪个辅助缓冲器(AUX1/AUX2)*
				* -----------------------------------------------------------------------------*
				*  bit 0  Set_Prm: Set (Extended) Parameter                                    *
				*   0 = Aux-Buffer 1 														
				*   1 = Aux-Buffer 2														
				* -----------------------------------------------------------------------------*
				*  bit 1  Chk_Cfg: Check Configuration                                         *
				*   0 = Aux-Buffer 1 														
				*   1 = Aux-Buffer 2														
				* -----------------------------------------------------------------------------*
				*  bit 2  Set_Slave_Adr: Set Slave Address                                     *
				*   0 = Aux-Buffer 1 														
				*   1 = Aux-Buffer 2													

	(4)、*pwAuxLen= 指向存储有“辅助缓冲器1长度”和“辅助缓冲器2长度”数组的指针。


   入口实参:
	(1)、pwLens[0] = real_buf_len[RBL_PRM] = 64 (用户程序定义的参数缓冲器长度) 
	(2)、pwLens[1] = real_buf_len[RBL_CFG] = 64 (用户程序定义的配置缓冲器长度)
	(3)、pwLens[2] = real_buf_len[RBL_SSA] =  0 (用户程序定义的站地址缓冲器长度)
	(4)、bCount = 3 (表示pwLens数组有3个向量。表示函数将根据参数缓冲器、配置缓冲器、站地址缓冲器这3个缓冲器来分配辅助缓冲器1和辅助缓冲器2)
	(5)、pbAssign =    随机数(注:该入口参数的实参无意义,因为函数中计算出的值通过指针返回给入口实参调用者)
	(6)、pwAuxLen[0] = 随机数(注:该入口参数的实参无意义,因为函数中计算出的值通过指针返回给入口实参调用者)
	(7)、pwAuxLen[1] = 随机数(注:该入口参数的实参无意义,因为函数中计算出的值通过指针返回给入口实参调用者)

    出口参数:
	(1)、pbAssign = 0 (表示:参数缓冲器、配置缓冲器、站地址缓冲器均选择辅助缓冲器1管理控制。  
	(2)、pwAuxLen[0] = 64 (表示:辅助缓冲器1分配了64字节内存空间)
	(3)、pwAuxLen[1] = 0 (表示:辅助缓冲器2分配了0字节内存空间,即:没有启用辅助缓冲器2)
	(4)、pwLens[0] = 64 (经过辅助缓冲器修改后的参数缓冲器长度)
	(5)、pwLens[0] = 64(经过辅助缓冲器修改后的配置缓冲器长度)

    局部变量:
	       wMinLen =  192 = 参数缓冲器长度+配置缓冲器长度+站地址缓冲器长度+辅助缓冲器长度	
	
    返回值:
	       UWORD =  192 = 参数缓冲器、配置缓冲器、站地址缓冲器、辅助缓冲器1、辅助缓冲器2 这5个缓冲器占用空间大小。  			        

    调用格式:
		dp_sys.vpc3_used_dp_buf_mem = assign_aux_buf(&real_buf_len[0], 3, &aux_ass, &aux_buf_len[0]);

 
    函数功能:








//-------------------------------------------------------------------------------------
1. 执行下面语句 
//-------------------------------------------------------------------------------------
    if (( bCount == 2 ) || ( bCount == 3 ))

已知:
	bCount = 3


目的:
	判断入口参数指定的pwLens数组向量是否合法。
        如果用户禁止站地址功能,必须至少指定参数缓冲器和配置缓冲器这2个缓冲器,才允许给辅助缓冲器进行分配工作。
	如果用户允许站地址功能,必须至少指定参数缓冲器、配置缓冲器和站地址缓冲器这3个缓冲器,才允许给辅助缓冲器进行分配工作。

结果:

       逻辑条件结果为真。





//-------------------------------------------------------------------------------------
2. 执行下面语句 
//-------------------------------------------------------------------------------------
	for ( i = 0; i < bCount; i++ )
        {
            // init memory for position of length
            bPos[i] = i;
            // copy length into workarea for calculated length
            wLensx[i] = pwLens[i];
            // put length to 8 Bit Segmentaddresses
            wLensx[i] = (wLensx[i] + SEG_OFFSET) & SEG_ADDWORD;
        }

已知:
	(1)、bCount = 3
	(2)、pwLens[0] = 64
	(3)、pwLens[1] = 64
	(4)、pwLens[2] = 0
	(5)、SEG_OFFSET = 0x07
	(6)、SEG_ADDBYTE = 0xF8

目的:
	
	(1)、把入口参数保存的pwLens[0](参数缓冲器长度)、pwLens[1](配置缓冲器长度)、pwLens[2](站地址缓冲器长度)凑成8的倍数,保存到数组wLensx[i]中。
	(2)、数组bPos[i]中保存数组pwLens[i]的下标
 
结果:

       (1)、wLensx[0] = (64+7)&0xF8 = 64
       (2)、wLensx[1] = (64+7)&0xF8 = 64
       (3)、wLensx[2] = (0+7)&0xF8 = 0

       (4)、bPos[0] = 0   ----> bPos[0]=0指示wLensx[0]中保存的是参数缓冲器的长度
       (5)、bPos[1] = 1   ----> bPos[1]=1指示wLensx[1]中保存的是配置缓冲器的长度
       (6)、bPos[2] = 2   ----> bPos[2]=2指示wLensx[2]中保存的是站地址缓冲器的长度





//-------------------------------------------------------------------------------------
3. 执行下面语句 
//-------------------------------------------------------------------------------------
        // sort length, highest length to index 0
        for( i = 0; i < bCount-1; i++ )
        {
            for( j = i+1; j < bCount; j++ )
            {
                if( wLensx[i] < wLensx[j] ) 
                {
                    // found higher length
                    //V504
                    wTmp = wLensx[i];          // swap length
                    wLensx[i] = wLensx[j];
                    wLensx[j] = wTmp;

                    bTmp = bPos[i];            // swap position
                    bPos[i] = bPos[j];
                    bPos[j] = bTmp;
                }
            }
        }

已知:
	(1)、bCount = 3
	(2)、wLensx[0] = 64
	(3)、wLensx[1] = 64
	(4)、wLensx[2] = 0

	(5)、bPos[0] = 0 
	(6)、bPos[1] = 1 
	(7)、bPos[2] = 2 

目的:
	
	 执行排序(从大到小的排序)。其中:wLensx[]数组中存放的是排序的数值,数组bPos[]存放的是排序前wLensx[]数组中存放的数值的下标)
 
结果:

       (1)、wLensx[0] = 64
       (2)、wLensx[1] = 64
       (3)、wLensx[2] = 0

       (4)、bPos[0] = 0   ----> 排序后,bPos[0]=0指示wLensx[0]中保存的是参数缓冲器的长度
       (5)、bPos[1] = 1   ----> 排序后,bPos[1]=1指示wLensx[1]中保存的是配置缓冲器的长度
       (6)、bPos[2] = 2   ----> 排序后,bPos[2]=2指示wLensx[2]中保存的是站地址缓冲器的长度






//-------------------------------------------------------------------------------------
4. 执行下面语句 
//-------------------------------------------------------------------------------------
        // delete zero length from list lensx
        for ( i = bCount; i > 0; i-- )
        {
            if (wLensx[i-1] == 0)
            {
                bCount--;
            }
        }


已知:
	(1)、bCount = 3
	(2)、wLensx[0] = 64
	(3)、wLensx[1] = 64
	(4)、wLensx[2] = 0


目的:
	
	 如果数组wLensx[]中发现数值为0的向量,即:则该缓冲器将不参与辅助缓冲器长度的分配工作。
 
结果:

	(1)、bCount = 2  (由于站地址缓冲器长度=0,则只有参数缓冲器和配置缓冲器这2个缓冲器参与辅助缓冲器长度的分配工作)






//-------------------------------------------------------------------------------------
5. 执行下面语句 
//-------------------------------------------------------------------------------------
        if ( bCount == 0 )
        {
            wMinLen = 0;     // Error: no defined buffer length
        }


已知:
	(1)、bCount = 2


目的:
	
	 如果数组wLensx[0]、wLensx[1]、wLensx[2]中数值全部为0,则返回已占用内存空间=0。
	 即:返回值 = 参数缓冲器、配置缓冲器、站地址缓冲器、辅助缓冲器1、辅助缓冲器2 这5个缓冲器占用空间大小 = 0
 
结果:

	逻辑条件结果为假。(因为参数缓冲器和配置缓冲器长度都为64)






//-------------------------------------------------------------------------------------
6. 执行下面语句 
//-------------------------------------------------------------------------------------
        wLensx[0] = 63;(人为的将wLensx[0]由64修改为63,观察程序运行情况)

        // gradual(逐渐的) length assign to aux-buffer
        for ( bStep = 0; bStep < bCount; bStep++ )
        {
            // get length for AUX-Buffer 1
            pwAuxLen[0] = 0;

            for ( i = bStep; i < bCount; i++ )
            {
                if( pwAuxLen[0] < wLensx[i] )
                {
                    pwAuxLen[0] = wLensx[i];
                }
            }
            pwAuxLen[0] = pwAuxLen[0] * (bCount - bStep + 1);

            // get length for AUX-Buffer 2
            pwAuxLen[1] = 0;
            
            for ( i = 0; i < bStep; i++ )
            {
                if ( pwAuxLen[1] < wLensx[i] )
                {
                    pwAuxLen[1] = wLensx[i];
                }
	    }

            pwAuxLen[1] = pwAuxLen[1] * (bStep + 1);
            if ((pwAuxLen[0] + pwAuxLen[1]) < wMinLen )
            {
                // new minimal length found
                wMinLen = pwAuxLen[0] + pwAuxLen[1];
                bMinStep = bStep;
            }
        }


已知:
	(1)、bCount = 2
	(2)、wLensx[0] = 63 (人为的将wLensx[0]由64修改为63,观察程序运行情况)
	(3)、wLensx[1] = 64
        (4)、bPos[0] = 0   ----> bPos[0]=0指示wLensx[0]中保存的是参数缓冲器的长度
        (5)、bPos[1] = 1   ----> bPos[1]=1指示wLensx[1]中保存的是配置缓冲器的长度
目的:
	
	 pwAuxLen[0]
	 
 
结果:

	(1)、pwAuxLen[0] = 128 (第二趟计算的辅助1缓冲器+参数缓冲器+配置缓冲器最大空间)
	(2)、pwAuxLen[1] = 126 (第二趟计算的辅助2缓冲器+参数缓冲器+配置缓冲器最大空间)
	(3)、wMinLen = 192 (第一趟找到的最小合适空间)
	(4)、bMinStep = 0  (做标记,bMinStep = 0 表示是第一趟找到的)





/
//				第一趟循环
/
//-------------------------------------------------------------------------------------------------------
6-1-1. 执行下面语句   -------->第一趟循环追踪(wLensx[0] = 63,wLensx[1] = 64,bCount = 2,bStep = 0)
//-------------------------------------------------------------------------------------------------------
      // get length for AUX-Buffer 1 
       pwAuxLen[0] = 0;

       for ( i = bStep; i < bCount; i++ )
       {
            if( pwAuxLen[0] < wLensx[i] )
            {
                pwAuxLen[0] = wLensx[i];
            }
       }
   
已知:
	(1)、pwAuxLen[0] = 0

目的:   
	 数组单元wLensx[0]wLensx[1]和中找到最大值存放到数组单元pwAuxLen[0]
 
结果:
	 pwAuxLen[0] = 64





//-------------------------------------------------------------------------------------------------------
6-1-2. 执行下面语句   -------->第一趟循环追踪(wLensx[0] = 63,wLensx[1] = 64,bCount = 2,bStep = 0)
//-------------------------------------------------------------------------------------------------------

 	pwAuxLen[0] = pwAuxLen[0] * (bCount - bStep + 1);


已知:
	(1)、pwAuxLen[0] = 64


目的:   
	 计算辅助1缓冲器+参数缓冲器+配置缓冲器最大空间(由于站地址缓冲器长度=0,因此程序代码中不考虑站地址缓冲器)
 
结果:
	 pwAuxLen[0] = pwAuxLen[0] * (bCount - bStep + 1) = 64 * (2 - 0 + 1) = 64 * 3 = 192




//-------------------------------------------------------------------------------------------------------
6-1-3. 执行下面语句   -------->第一趟循环追踪(wLensx[0] = 63,wLensx[1] = 64,bCount = 2,bStep = 0)
//-------------------------------------------------------------------------------------------------------
            // get length for AUX-Buffer 2
            pwAuxLen[1] = 0;
            
            for ( i = 0; i < bStep; i++ )
            {
                if ( pwAuxLen[1] < wLensx[i] )
                {
                    pwAuxLen[1] = wLensx[i];
                }
	}

已知:
	(1)、pwAuxLen[1] = 0

目的:   
	 数组单元wLensx[0]wLensx[1]和中找到最大值存放到数组单元pwAuxLen[1]
	 由于bStep = 0,所以FOR 循环不执行
 
结果:
	(1)、pwAuxLen[1] = 0



//-------------------------------------------------------------------------------------------------------
6-1-4. 执行下面语句   -------->第一趟循环追踪(wLensx[0] = 63,wLensx[1] = 64,bCount = 2,bStep = 0)
//-------------------------------------------------------------------------------------------------------
            pwAuxLen[1] = pwAuxLen[1] * (bStep + 1);

已知:
	(1)、pwAuxLen[1] = 0

目的:   
	 计算辅助2缓冲器+参数缓冲器+配置缓冲器最大空间(由于站地址缓冲器长度=0,因此程序代码中不考虑站地址缓冲器)
	
 
结果:
	(1)、pwAuxLen[1] = pwAuxLen[1] * (bStep + 1) = 0 * (0+1) = 0




//-------------------------------------------------------------------------------------------------------
6-1-5. 执行下面语句   -------->第一趟循环追踪(wLensx[0] = 63,wLensx[1] = 64,bCount = 2,bStep = 0)
//-------------------------------------------------------------------------------------------------------
            if ((pwAuxLen[0] + pwAuxLen[1]) < wMinLen )
            {
                // new minimal length found
                wMinLen = pwAuxLen[0] + pwAuxLen[1];
                bMinStep = bStep;
            }

已知:
	(1)、pwAuxLen[0] = 192
	(2)、pwAuxLen[1] = 0
	(3)、wMinLen = 0xFFFF
目的:   
	 辅助2缓冲器+参数缓冲器+配置缓冲器最大空间 和 辅助1缓冲器+参数缓冲器+配置缓冲器最大空间 找最小值,即:找最小空间。
	
 
结果:
	(1)、wMinLen = pwAuxLen[0] + pwAuxLen[1] = 192 + 0 = 192  (第一趟找到的最小合适空间)
	(2)、bMinStep = 0 (做标记,bMinStep = 0 表示是第一趟找到的)





/
//				第二趟循环
/
//-------------------------------------------------------------------------------------------------------
6-2-1. 执行下面语句   -------->第二趟循环追踪(wLensx[0] = 63,wLensx[1] = 64,bCount = 2,bStep = 1)
//-------------------------------------------------------------------------------------------------------
      // get length for AUX-Buffer 1 
       pwAuxLen[0] = 0;

       for ( i = bStep; i < bCount; i++ )
       {
            if( pwAuxLen[0] < wLensx[i] )
            {
                pwAuxLen[0] = wLensx[i];
            }
       }
   
已知:
	(1)、pwAuxLen[0] = 0

目的:   
	 数组单元wLensx[0]wLensx[1]和中找到最大值存放到数组单元pwAuxLen[0]
 	 由于bStep = 1,所以 i = bStep = 1 ,pwAuxLen[0] 直接和wLensx[1] 进行比较
结果:
	 pwAuxLen[0] = 64




//-------------------------------------------------------------------------------------------------------
6-2-2. 执行下面语句   -------->第二趟循环追踪(wLensx[0] = 63,wLensx[1] = 64,bCount = 2,bStep = 1)
//-------------------------------------------------------------------------------------------------------

 	pwAuxLen[0] = pwAuxLen[0] * (bCount - bStep + 1);


已知:
	(1)、pwAuxLen[0] = 64


目的:   
	 计算辅助1缓冲器+参数缓冲器+配置缓冲器最大空间(由于站地址缓冲器长度=0,因此程序代码中不考虑站地址缓冲器)
 
结果:
	 pwAuxLen[0] = pwAuxLen[0] * (bCount - bStep + 1) = 64 * (2 - 1 + 1) = 64 * 2 = 128






//-------------------------------------------------------------------------------------------------------
6-2-3. 执行下面语句   -------->第二趟循环追踪(wLensx[0] = 63,wLensx[1] = 64,bCount = 2,bStep = 1)
//-------------------------------------------------------------------------------------------------------
            // get length for AUX-Buffer 2
            pwAuxLen[1] = 0;
            
            for ( i = 0; i < bStep; i++ )
            {
                if ( pwAuxLen[1] < wLensx[i] )
                {
                    pwAuxLen[1] = wLensx[i];
                }
	}

已知:
	(1)、pwAuxLen[1] = 0

目的:   
	 数组单元wLensx[0]wLensx[1]和中找到最大值存放到数组单元pwAuxLen[1]
	 由于bStep = 1,所以 当i = 0 时,FOR循环条件满足,pwAuxLen[1] 和wLensx[0] 进行比较
                            
 
结果:
	(1)、pwAuxLen[1] = 63



//-------------------------------------------------------------------------------------------------------
6-2-4. 执行下面语句   -------->第一趟循环追踪(wLensx[0] = 63,wLensx[1] = 64,bCount = 2,bStep = 1)
//-------------------------------------------------------------------------------------------------------
            pwAuxLen[1] = pwAuxLen[1] * (bStep + 1);

已知:
	(1)、pwAuxLen[1] = 63

目的:   
	 计算辅助2缓冲器+参数缓冲器+配置缓冲器最大空间(由于站地址缓冲器长度=0,因此程序代码中不考虑站地址缓冲器)
	
 
结果:
	(1)、pwAuxLen[1] = pwAuxLen[1] * (bStep + 1) = 63 * (1+1) = 126




//-------------------------------------------------------------------------------------------------------
6-2-5. 执行下面语句   -------->第一趟循环追踪(wLensx[0] = 63,wLensx[1] = 64,bCount = 2,bStep = 1)
//-------------------------------------------------------------------------------------------------------
            if ((pwAuxLen[0] + pwAuxLen[1]) < wMinLen )
            {
                // new minimal length found
                wMinLen = pwAuxLen[0] + pwAuxLen[1];
                bMinStep = bStep;
            }

已知:
	(1)、pwAuxLen[0] = 128
	(2)、pwAuxLen[1] = 126
	(3)、wMinLen = 192 (第一趟循环时,计算得到的值等于192)
	(4)、bMinStep = 0 (做标记,bMinStep = 0 表示是第一趟找到的)

目的:   
	 辅助2缓冲器+参数缓冲器+配置缓冲器最大空间 和 辅助1缓冲器+参数缓冲器+配置缓冲器最大空间 找最小值,即:找最小空间。
	
 
结果:
	(1)、wMinLen = 192  (第一趟找到的最小合适空间)
	(2)、bMinStep = 0 (做标记,bMinStep = 0 表示是第一趟找到的)

         由于pwAuxLen[0] + pwAuxLen[1] = 128 + 126 = 254 > 第一趟找到的最小空间192,因此IF语句中的内容不执行。








//-------------------------------------------------------------------------------------
7. 执行下面语句 
//-------------------------------------------------------------------------------------
       
        // calculate length for AUX Buffer 1
        pwAuxLen[0] = 0;

        for ( i = bMinStep; i < bCount; i++ )
        {
            if (pwAuxLen[0] < wLensx[i])
            {
                pwAuxLen[0] = wLensx[i];
            }
        }


已知:
	(1)、pwAuxLen[0] = 0
	(2)、bMinStep = 0 (做标记,bMinStep = 0 表示是第一趟找到的)
	(3)、wLensx[0] = 63 (人为的将wLensx[0]由64修改为63,观察程序运行情况)
	(4)、wLensx[1] = 64

目的:   
	 辅助1缓冲器+参数缓冲器+配置缓冲器最大空间 和 辅助1缓冲器+参数缓冲器+配置缓冲器最大空间
	
 
结果:
	(1)、pwAuxLen[0] = 64






//-------------------------------------------------------------------------------------
8. 执行下面语句 
//-------------------------------------------------------------------------------------
        // put length, assigned for AUX buffer 1
        for (i = bMinStep; i < bCount; i++)
        {
            pwLens[bPos[i]] = pwAuxLen[0];
        }


已知:
	(1)、pwAuxLen[0] = 64
	(2)、bMinStep = 0 (做标记,bMinStep = 0 表示是第一趟找到的)
	(3)、wLensx[0] = 63 (人为的将wLensx[0]由64修改为63,观察程序运行情况)
	(4)、wLensx[1] = 64
	(5)、bPos[0] = 0
	(6)、bPos[1] = 1


目的:   修改入口参数提供的参数缓冲器长度和配置缓冲器长度。
	 
	
 
结果:
	(1)、pwLens[0] = 64
	(2)、pwLens[1] = 64





//-------------------------------------------------------------------------------------
9. 执行下面语句 
//-------------------------------------------------------------------------------------
        // calculate length of AUX-Buffer 2
        pwAuxLen[1] = 0;

        for ( i = 0; i < bMinStep; i++)
        {
            if (pwAuxLen[1] < wLensx[i])
            {
                pwAuxLen[1] = wLensx[i];
            }
        }


已知:
	(1)、bMinStep = 0 (做标记,bMinStep = 0 表示是第一趟找到的)
	(2)、wLensx[0] = 63 (人为的将wLensx[0]由64修改为63,观察程序运行情况)
	(3)、wLensx[1] = 64
	(4)、pwAuxLen[1] = 0


目的:   再次修正辅助缓冲器2长度
	 
	 由于 bMinStep = 0 所以FOR循环不执行。
 
结果:
	(1)、pwAuxLen[1] = 0




//-------------------------------------------------------------------------------------
9. 执行下面语句 
//-------------------------------------------------------------------------------------

        *pbAssign = 0;    // put all buffer to AUX-Buffer 1

        for (i = 0; i < bMinStep; i++)
        {
            pwLens[bPos[i]] = pwAuxLen[1];
            *pbAssign |= 0x1 << bPos[i];
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值