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];
}