我们在第二节就分析到了 finishCollection( void ),但是当我们分析完第三节后,整个系统才真正执行到这里,我们依然像第二节一样把这个函数全部贴出来

  1. /*********************************************************************
  2. * @fn finishCollection
  3. *
  4. * @brief Sends the next Bind Node Response message
  5. *
  6. * @param none
  7. *
  8. * @return none
  9. */
  10. static void finishCollection( void )
  11. {
  12. if ((ZDO_Config_Node_Descriptor.CapabilityFlags & CAPINFO_RCVR_ON_IDLE) == 0)
  13. {
  14. uint8 x;
  15.  
  16. // Turn the receiver back off while idle
  17. x = false;
  18. ZMacSetReq( ZMacRxOnIdle, &x );
  19. }
  20.  
  21. // Send the Blind node response
  22. sendRsp();
  23.  
  24. if ( config.mode == NODE_MODE_AUTO )
  25. {
  26. // set up next auto response
  27. osal_start_timerEx( BlindNode_TaskID, BLINDNODE_FIND_EVT, config.cycle );
  28. defAddr.addrMode = afAddr16Bit;
  29. defAddr.addr.shortAddr = config.dstAddr;
  30. defAddr.endPoint = config.dstEp;
  31. }
  32.  
  33. state = eBnIdle;
  34. }

 

其它不解释了,具体参见第二节,我们下面直接进入函数sendRsp

  1. /*********************************************************************
  2. * @fn sendRsp
  3. *
  4. * @brief Build and send the response message.
  5. *
  6. * @param None.
  7. *
  8. * @return status from call to AF_DataRequest().
  9. */
  10. static afStatus_t sendRsp( void )
  11. {
  12. uint8 msg[BLINDNODE_RESPONSE_LEN];
  13. LocRefNode_t locNodes[BLINDNODE_MAX_REF_NODES];
  14. uint16 xOff, yOff;
  15. uint8 idx, cnt = 0;
  16.  
  17. for ( idx = 0; idx < rspCnt; idx++ )
  18. {
  19. BLINDNODE_CONV_RSSI( refNodes[idx].rssi );
  20. if ( refNodes[idx].rssi != 0 )
  21. {
  22. cnt++;
  23. }
  24. }
  25.  
  26. if ( cnt >= config.minRefNodes )
  27. {
  28. msg[BLINDNODE_RESPONSE_STATUS_IDX] = BLINDNODE_RSP_STATUS_SUCCESS;
  29.  
  30. // Sort the ref nodes by RSSI in order to pass the best 16 to loc engine.
  31. rspCnt = sortNodes( refNodes );
  32.  
  33. calcOffsets( refNodes, &xOff, &yOff );
  34.  
  35. // Convert to logical coordinates.
  36. setLogicals( locNodes, refNodes, xOff, yOff );
  37.  
  38. // Run the location calculation
  39. locationCalculatePosition( locNodes, &(config.loc) );
  40.  
  41. // Convert results to real coordinates and average over several samples.
  42. xOff += config.loc.x;
  43. yOff += config.loc.y;
  44.  
  45. if ( ((xOff > xOld) && ((xOff - xOld) > BLINDNODE_FLUSH)) ||
  46. ((xOff < xOld) && ((xOld - xOff) > BLINDNODE_FLUSH)) ||
  47. ((yOff > yOld) && ((yOff - yOld) > BLINDNODE_FLUSH)) ||
  48. ((yOff < yOld) && ((yOld - yOff) > BLINDNODE_FLUSH)) )
  49. {
  50. xOld = xOff;
  51. yOld = yOff;
  52. }
  53. else
  54. {
  55. xOld = ((xOld * (BLINDNODE_FILTER-1)) + xOff) / BLINDNODE_FILTER;
  56. yOld = ((yOld * (BLINDNODE_FILTER-1)) + yOff) / BLINDNODE_FILTER;
  57. }
  58.  
  59. xOff = (uint16)xOld;
  60. yOff = (uint16)yOld;
  61. }
  62. else
  63. {
  64. msg[BLINDNODE_RESPONSE_STATUS_IDX] = BLINDNODE_RSP_STATUS_NOT_ENOUGH_REFNODES;
  65.  
  66. xOff = (uint16)xOld;
  67. yOff = (uint16)yOld;
  68. }
  69. rspMsg[REFNODE_CONFIG_X_LO_IDX] =
  70. msg[BLINDNODE_RESPONSE_X_LO_IDX] = LO_UINT16( xOff );
  71. rspMsg[REFNODE_CONFIG_X_HI_IDX] =
  72. msg[BLINDNODE_RESPONSE_X_HI_IDX] = HI_UINT16( xOff );
  73. rspMsg[REFNODE_CONFIG_Y_LO_IDX] =
  74. msg[BLINDNODE_RESPONSE_Y_LO_IDX] = LO_UINT16( yOff );
  75. rspMsg[REFNODE_CONFIG_Y_HI_IDX] =
  76. msg[BLINDNODE_RESPONSE_Y_HI_IDX] = HI_UINT16( yOff );
  77.  
  78. msg[BLINDNODE_RESPONSE_NUMREFNODES_IDX] = cnt;
  79.  
  80. if ( rspCnt != 0 )
  81. {
  82. msg[BLINDNODE_RESPONSE_REF_SHORTADDR_LO_IDX] = LO_UINT16( refNodes->addr );
  83. msg[BLINDNODE_RESPONSE_REF_SHORTADDR_HI_IDX] = HI_UINT16( refNodes->addr );
  84. msg[BLINDNODE_RESPONSE_REF_X_LO_IDX] = LO_UINT16( refNodes->x );
  85. msg[BLINDNODE_RESPONSE_REF_X_HI_IDX] = HI_UINT16( refNodes->x );
  86. msg[BLINDNODE_RESPONSE_REF_Y_LO_IDX] = LO_UINT16( refNodes->y );
  87. msg[BLINDNODE_RESPONSE_REF_Y_HI_IDX] = HI_UINT16( refNodes->y );
  88. msg[BLINDNODE_RESPONSE_REF_RSSI] = refNodes->rssi;
  89. }
  90. else
  91. {
  92. msg[BLINDNODE_RESPONSE_REF_SHORTADDR_LO_IDX] = LO_UINT16( INVALID_NODE_ADDR );
  93. msg[BLINDNODE_RESPONSE_REF_SHORTADDR_HI_IDX] = HI_UINT16( INVALID_NODE_ADDR );
  94. msg[BLINDNODE_RESPONSE_REF_X_LO_IDX] = LO_UINT16( LOC_DEFAULT_X_Y );
  95. msg[BLINDNODE_RESPONSE_REF_X_HI_IDX] = HI_UINT16( LOC_DEFAULT_X_Y );
  96. msg[BLINDNODE_RESPONSE_REF_Y_LO_IDX] = LO_UINT16( LOC_DEFAULT_X_Y );
  97. msg[BLINDNODE_RESPONSE_REF_Y_HI_IDX] = HI_UINT16( LOC_DEFAULT_X_Y );
  98. msg[BLINDNODE_RESPONSE_REF_RSSI] = 0xFF;
  99. }
  100.  
  101. osal_start_timerEx( BlindNode_TaskID, BLINDNODE_WAIT_EVT, 1000 );
  102.  
  103. return ( AF_DataRequest( &defAddr, (endPointDesc_t *)&epDesc,
  104. LOCATION_BLINDNODE_FIND_RESPONSE,
  105. BLINDNODE_RESPONSE_LEN, msg,
  106. &transId, 0, AF_DEFAULT_RADIUS ) );
  107. }

这个函数code比较长,而且里面还调用了很多函数,如果我们分析完这个函数CC2431 盲节点的代码也就分析完了(除盲节点配置外)。

我们一点一点分析这个函数的内容,首先

  1. for ( idx = 0; idx < rspCnt; idx++ )
  2. {
  3. BLINDNODE_CONV_RSSI( refNodes[idx].rssi );
  4. if ( refNodes[idx].rssi != 0 )
  5. {
  6. cnt++;
  7. }
  8. }

  一个for 循环,循环的次数是rspCnt这个全局变量,它是值的大小在CC2431盲节点接收收据的时候被赋值,表示了有多少个CC2430参考节点回应数据,具体这个量随实际情况变换。 后面有个宏BLINDNODE_CONV_RSSI( refNodes[idx].rssi );

  1. #define BLINDNODE_CONV_RSSI( lqi ) \
  2. st ( \
  3. if ( lqi <= BLINDNODE_MIN_RSSI ) \
  4. lqi = 0; \
  5. else if ( lqi >= BLINDNODE_MAX_RSSI ) \
  6. lqi = -LOC_ENGINE_MAX_DBM; \
  7. else \
  8. lqi = -BLINDNODE_MIN_DBM - ((uint8)(((uint16)(lqi) * _ED_RF_POWER_DELTA) / _MAC_SPEC_ED_MAX)); \
  9. )

  这个宏的最大作用是 将RSSI做换成LQI,并且要考虑RSSI最大最小情况。 RSSI与LQI的关系参见博文http://lfwendula0.blog.163.com/blog/static/20513823620127282719319/,从这里我们可以看出,其实实际在计算距离的时候是用的LQI。

下面在接着分析代码

  1. if ( cnt >= config.minRefNodes )
  2. {
  3. msg[BLINDNODE_RESPONSE_STATUS_IDX] = BLINDNODE_RSP_STATUS_SUCCESS;
  4.  
  5. // Sort the ref nodes by RSSI in order to pass the best 16 to loc engine.
  6. rspCnt = sortNodes( refNodes );
  7.  
  8. calcOffsets( refNodes, &xOff, &yOff );
  9.  
  10. // Convert to logical coordinates.
  11. setLogicals( locNodes, refNodes, xOff, yOff );
  12.  
  13. // Run the location calculation
  14. locationCalculatePosition( locNodes, &(config.loc) );
  15.  
  16. // Convert results to real coordinates and average over several samples.
  17. xOff += config.loc.x;
  18. yOff += config.loc.y;
  19.  
  20. if ( ((xOff > xOld) && ((xOff - xOld) > BLINDNODE_FLUSH)) ||
  21. ((xOff < xOld) && ((xOld - xOff) > BLINDNODE_FLUSH)) ||
  22. ((yOff > yOld) && ((yOff - yOld) > BLINDNODE_FLUSH)) ||
  23. ((yOff < yOld) && ((yOld - yOff) > BLINDNODE_FLUSH)) )
  24. {
  25. xOld = xOff;
  26. yOld = yOff;
  27. }
  28. else
  29. {
  30. xOld = ((xOld * (BLINDNODE_FILTER -1)) + xOff) / BLINDNODE_FILTER;
  31. yOld = ((yOld * (BLINDNODE_FILTER-1)) + yOff) / BLINDNODE_FILTER;
  32. }
  33.  
  34. xOff = (uint16)xOld;
  35. yOff = (uint16)yOld;
  36. }

  上面贴出的代码是满足条件 cnt >= config.minRefNodes,也就是通过前面的code分析,并最终获得的可用参考节点数量大于config.minRefNodes,通常config.minRefNodes这个值定义为3,因为算法是三边定位,最小需要三个节点。当然可以设置为4 或者更大的值(如果系统中只有三个节点,设置成4则永远无法实现定位)。后面else 部分的code 没有贴出来,后面的代码就是没有足够多的参考节点使用上次的坐标信息。

  如果这个if 条件里的code分析完,CC431的代码也就基本完事了。我们分别看里面的几个主要函数。

   rspCnt = sortNodes( refNodes );  

  1. /*********************************************************************
  2. * @fn sortNodes
  3. *
  4. * @brief Sorts the nodes into a list with the best to least RSSI
  5. *
  6. * INPUTS: ref - Array of reference nodes w/ RSSI values converted for
  7. * location engine from 40 (strong) to 95 (weak) & zero = too week.
  8. *
  9. * OUTPUTS: none
  10. *
  11. * @return Count of non-zero RSSI entries.
  12. */
  13. static uint8 sortNodes( RefNode_t *ref )
  14. {
  15. RefNode_t *workNodes;
  16. uint8 idx;
  17.  
  18. workNodes = osal_mem_alloc( sizeof( RefNode_t ) * rspCnt );
  19.  
  20. if ( workNodes == NULL )
  21. {
  22. return 0;
  23. }
  24.  
  25. osal_memcpy( workNodes, ref, sizeof( RefNode_t ) * rspCnt );
  26.  
  27. for ( idx = 0; idx < rspCnt; idx++ )
  28. {
  29. RefNode_t *node = findBestRSSI( workNodes );
  30.  
  31. if ( node == NULL )
  32. {
  33. break;
  34. }
  35. else
  36. {
  37. osal_memcpy( ref, node, sizeof( RefNode_t ) );
  38. node->addr = INVALID_NODE_ADDR;
  39. }
  40.  
  41. ref++;
  42. }
  43.  
  44. osal_mem_free( workNodes );
  45.  
  46. return idx;
  47. }

  这个函数的意义和代码很简单,就是把保存参考节点信息的数组按照RSSI(其实现在是LQI)的大小重新排序。具体为何排序,我的理解是定位引擎只会利用数组前面若干个参考节点的信息,后面的一部分是不用的。 假如这样想,CC2431收到150个参考节点的回复,而定位引擎只需要使用100个,那么最好的办法是使用最好的100个参考节点。

calcOffsets( refNodes, &xOff, &yOff );

  1. /*********************************************************************
  2. * @fn calcOffsets
  3. *
  4. * @brief Calculates the XY offsets.
  5. *
  6. * INPUTS:
  7. * @param ref - Array of reference nodes, pre-sorted on RSSI, best to worst.
  8. *
  9. * OUTPUTS:
  10. * @param xOff - pointer to X offset
  11. * param yOff - pointer to Y offset
  12. *
  13. * @return none
  14. */
  15. static void calcOffsets( RefNode_t *ref, uint16 *xOff, uint16 *yOff )
  16. {
  17. RefNode_t *rnP = ref;
  18. uint16 xMax = 0;
  19. uint16 yMax = 0;
  20. uint8 idx;
  21.  
  22. for ( idx = 0; idx < rspCnt; idx++ )
  23. {
  24. if ( xMax < rnP->x )
  25. {
  26. xMax = rnP->x;
  27. }
  28. if ( yMax < rnP->y )
  29. {
  30. yMax = rnP->y;
  31. }
  32.  
  33. rnP++;
  34. }
  35.  
  36. // No need for conversion.
  37. if ( (xMax < 256) && (yMax < 256) )
  38. {
  39. *xOff = *yOff = 0;
  40. }
  41. else
  42. {
  43. // Force reference node with the best RSSI to sit at logical (32,32).
  44. *xOff = (ref->x & 0xFFFC) - 128;
  45. *yOff = (ref->y & 0xFFFC) - 128;
  46. }
  47. }

  这个函数就比较难以理解了,其实简单一说,就觉得哦原来这样。首先我们我们知道CC2431定位范围是64*64平米的一个范围,但这个是一个CC2431所能覆盖的范围,但并不是一个系统的范围,定位系统可以覆盖的范围几百几千米,具体要看参考节点的范围。为何CC2431只能覆盖64*64 平米,因为CC2431使用8 bit 作为传入参数,定位精度0.25米。 2^8 * 0.25 =64.

下面我们画几张图理解一下

第一张图: 常规应用,红色为2431,黑色为参考节点,所有的节点都在64 * 64 平米内

第二张图

下面这张图片是一个大系统的定位,不只是64*64平范围了,那么CC2431不能定位吗? 可以,我们可以计算偏移实现。

相对上面的(0,0) 坐标,现在变成了(100,100). 计算偏移的方法其实很简单,就是强制把参考节点中最好的一个强制换成(32,32)

第三张图片

我们强制把下面的一个节点的坐标换成(32,32),(我们假定离CC2431节点越近RSSI越好)。那么这个这点的做换过程出来的值就是偏移。假定开始的坐标是(112,113).那么偏移量分别是(80,81).

好了,到这里看完三张图片, calcOffsets 这个函数也就理解完了。

setLogicals( locNodes, refNodes, xOff, yOff );

  1. /*********************************************************************
  2. * @fn setLogicals
  3. *
  4. * @brief Sets the reference node's logical coordinates & RSSI for the
  5. * required number of inputs to the location engine.
  6. *
  7. * INPUTS:
  8. * @param ref - array of reference nodes
  9. * @param offsetX - X offset used to make logical numbers
  10. * param offsetY - Y offset used to make logical numbers
  11. *
  12. * @return none
  13. */
  14. static void setLogicals( LocRefNode_t *loc, RefNode_t *ref,
  15. uint16 xOff, uint16 yOff )
  16. {
  17. // Rev-B Chip have LocEng Ver 1.0 w/ cap=8, Rev-C have LocEng Ver 2.0 w/ 16.
  18. const uint8 stop = ( ( CHVER == 0x01 ) ? LOC_ENGINE_NODE_CAPACITY_REVB :
  19. LOC_ENGINE_NODE_CAPACITY_REVC);
  20. uint16 xTmp, yTmp;
  21. uint8 idx;
  22.  
  23. // Set the logical coordinates
  24. for ( idx = 0; idx < rspCnt; idx++ )
  25. {
  26. xTmp = ref->x - xOff;
  27. yTmp = ref->y - yOff;
  28.  
  29. if ( (xTmp < 256) && (yTmp < 256) )
  30. {
  31. loc->x = (uint8)xTmp;
  32. loc->y = (uint8)yTmp;
  33. loc->rssi = ref->rssi;
  34. }
  35. else
  36. {
  37. // Out of bounds, so feed zero to location engine.
  38. loc->x = loc->y = loc->rssi = 0;
  39. }
  40.  
  41. loc++;
  42. ref++;
  43. }
  44.  
  45. for ( ; idx < stop; idx++ )
  46. {
  47. // Feed zero to location engine to meet the required number of inputs.
  48. loc->x = loc->y = 0;
  49. loc->rssi = 0;
  50. loc++;
  51. }
  52. }

  这个函数的意义也很简单, 上面不是我们已经计算出一个偏移了,但是其他节点都是用的实际坐标,我们需要将所有节点的坐标都转换一下。

  

  1. // Set the logical coordinates
  2. for ( idx = 0; idx < rspCnt; idx++ )
  3. {
  4. xTmp = ref->x - xOff;
  5. yTmp = ref->y - yOff;
  6.  
  7. if ( (xTmp < 256) && (yTmp < 256) )
  8. {
  9. loc->x = (uint8)xTmp;
  10. loc->y = (uint8)yTmp;
  11. loc->rssi = ref->rssi;
  12. }
  13. else
  14. {
  15. // Out of bounds, so feed zero to location engine.
  16. loc->x = loc->y = loc->rssi = 0;
  17. }
  18.  
  19. loc++;
  20. ref++;
  21. }

  后面有个判断,如果转换后的坐标信息大于(64,64),则把RSSI的值设置为0, 因为2431 只能利用64*64(相对来说)范围内的信息。

上面坐标信息做换完成了,下面就是定位了

locationCalculatePosition( locNodes, &(config.loc) );

这个函数具体内容不分析了,可以查看CC2431的数据手册。 CC2430与CC2431的区别就这个部分,如果这个函数用软件实现了,那么定位就无需用CC2431芯片了。

定位完成后,出来的坐标信息是相对的,我们需要加上之前计算的偏移量就是真正的坐标了

  1. // Convert results to real coordinates and average over several samples.
  2. xOff += config.loc.x;
  3. yOff += config.loc.y;

  

滤波算法,TI知道CC2431使用RSSI定位有些精度上的问题,所以后面加了一个非常简答的滤波算法,有兴趣的同学可以实现更为高级的滤波算法, 我先简单分析一下Ti这个滤波算法

  1. if ( ((xOff > xOld) && ((xOff - xOld) > BLINDNODE_FLUSH)) ||
  2. ((xOff < xOld) && ((xOld - xOff) > BLINDNODE_FLUSH)) ||
  3. ((yOff > yOld) && ((yOff - yOld) > BLINDNODE_FLUSH)) ||
  4. ((yOff < yOld) && ((yOld - yOff) > BLINDNODE_FLUSH)) )
  5. {
  6. xOld = xOff;
  7. yOld = yOff;
  8. }
  9. else
  10. {
  11. xOld = ((xOld * (BLINDNODE_FILTER -1)) + xOff) / BLINDNODE_FILTER;
  12. yOld = ((yOld * (BLINDNODE_FILTER-1)) + yOff) / BLINDNODE_FILTER;
  13. }
  14.  
  15. xOff = (uint16)xOld;
  16. yOff = (uint16)yOld;

  

  

CC2431定位套餐推荐:https://item.taobao.com/item.htm?id=527836022363

CC2431 代码分析④-衣锦还乡的CC2431的更多相关文章

  1. CC2431 代码分析③-忍辱负重的CC2430

    这节主要分析CC2430的代码,是参考节点的代码,协调器代码我们放到最后分析. 代码分析的原则是事件为导向,我们从CC2431 盲节点code的分析中发现CC2431 向CC2430参考节点发送的信息 ...

  2. CC2431 代码分析②-CC2431狂轰滥炸

    CC2431 code review : CC2431 狂轰滥炸 在上一篇中的最后我们分析到CC2431 开始喊出第一声,这里我们逐步分析从第一声到后面的狂轰滥炸! 上代码 /************ ...

  3. CC2431 代码分析①-CC2431 喊出第一声

    CC2431 是一款可以基于RSSI 定位的 芯片. 定位原理,通过RSSI 强度换算距离. 可以打个类似的比方,一个人站在群山之间,每个山头都有一个地理坐标,然后大喊一声,各个方向会返回回声,通过回 ...

  4. Android代码分析工具lint学习

    1 lint简介 1.1 概述 lint是随Android SDK自带的一个静态代码分析工具.它用来对Android工程的源文件进行检查,找出在正确性.安全.性能.可使用性.可访问性及国际化等方面可能 ...

  5. pmd静态代码分析

    在正式进入测试之前,进行一定的静态代码分析及code review对代码质量及系统提高是有帮助的,以上为数据证明 Pmd 它是一个基于静态规则集的Java源码分析器,它可以识别出潜在的如下问题:– 可 ...

  6. [Asp.net 5] DependencyInjection项目代码分析-目录

    微软DI文章系列如下所示: [Asp.net 5] DependencyInjection项目代码分析 [Asp.net 5] DependencyInjection项目代码分析2-Autofac [ ...

  7. [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(5)(IEnumerable<>补充)

    Asp.net 5的依赖注入注入系列可以参考链接: [Asp.net 5] DependencyInjection项目代码分析-目录 我们在之前讲微软的实现时,对于OpenIEnumerableSer ...

  8. 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)

    构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...

  9. STM32启动代码分析 IAR 比较好

    stm32启动代码分析 (2012-06-12 09:43:31) 转载▼     最近开始使用ST的stm32w108芯片(也是一款zigbee芯片).开始看他的启动代码看的晕晕呼呼呼的. 还好在c ...

随机推荐

  1. Atom插件下载失败解决办法

    转自:http://www.cnblogs.com/20145221GQ/p/5334762.html#正题 一般方法(Atom自动安装) 打开Atom >> Packages >& ...

  2. rsa证书ssh登陆服务器

    好久不用,又生疏了. 今晚实操了一下,作一个记录. 使用rsa的密钥对登陆linux服务器,主要是为了安全. 这种证书级别的登陆,比最复杂的root用户名和帐号的安全性都要高一个等级. 至少服务器不会 ...

  3. C#学习-构造函数

    如果没有为类显式地定义一个构造函数,则C#编译器会自动生成一个函数体为空的默认无参的实例构造函数. 构造函数主要用于创建类的实例对象. 当调用构造函数创建一个对象时,构造函数会为对象分配内存空间,并初 ...

  4. C#使用Emit生成构造函数和属性

    假设我们需要一个名叫Kitty的类,其在Pets程序集下. 1 // specify a new assembly name 2 var assemblyName = new AssemblyName ...

  5. reconnecting-websocket.js

    websocket是HTML5下一个不错的网络协议解决方案,有一个场景很多猿猿都会遇到,手机锁屏后大约60秒,IOS会自动断开websocket连接,连接丢失了,那我们的数据也就断了.websocke ...

  6. ssm又乱码

    以前用mybatis的时候是这样的 mysql.connection.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characte ...

  7. mysql-5.7.10-winx64 绿色版安装办法

    mysql-5.7.10-winx64 绿色版安装办法 为了防止安装程序造成电脑系统冗余,经过测试,终于将绿色版的mysql for windows安装成功.当然很多是从事百度搜索到的,但作为一种积累 ...

  8. JMeter非GUI模式下日志介绍

    Creating summariser <summary> Created the tree successfully using /opt/JMeter/TestPlan/test.jm ...

  9. BZOJ2120 数颜色 莫队 带修莫队

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2120.html 题目传送门 - BZOJ2120 题意 给定一个长度为 $n$ 的序列 $a$ ,有 ...

  10. 认识Fiddler

    一.Fiddler界面介绍.(注:下图中的功能区面板显示的是“Inspectors”的选项卡界面) 二.工具栏介绍. 1.气泡:备注.添加之后在会话栏的Comment列中显示备注内容. 2.Repla ...