被改变的变量
自己定义的数组为SensorValue[7],为其每个元素赋了初值0x0000。 uint16_t SensorValue[7]={0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};//定义的数组 在程序中没有对SensorValue[]数组进行任何赋值操作,但是在程序运行过程中Debug该数组的值如下图所示: 发现数组的第一个元素SensorValue[0]被更改。
![]()
通过Keil查看变量地址来分析原因
在keil所在工程中用notepad++打开.map文件(里面可以看到所有变量的大小、地址等信息)。搜索出错的数组名SensorValue发现该数组的地址为0x24000208,大小为14个字节。
![]()
因为数组的第一个元素SensorValue[0]被更改,即该数组首地址处的数据被更改,所以我们查看该数组首地址0x24000208之前的一个地址的数据CAN3_spiReceiveBuffer是否越界操作到了SensorValue数组的数据。在程序中找到CAN3_spiReceiveBuffer定义: #define SPI_DEFAULT_BUFFER_LENGTH 96uint8_t CAN3_spiTransmitBuffer[SPI_DEFAULT_BUFFER_LENGTH];该数组为96个字节,在.map文件中查看确实为96个字节。
![]()
之后在keil中按Ctrl+F搜索所有的CAN3_spiTransmitBuffer(调试莫名Bug不就得这样)发现(只看下面程序的两句) int8_t CAN3_DRV_CANFDSPI_WriteByteArray(CANFDSPI_MODULE_ID index, uint16_t address, uint8_t *txd, uint16_t nBytes){ uint16_t CAN3_i; uint16_t spiTransferSize = nBytes + 2;//只看这里!!!!!! int8_t spiTransferError = 0; // Compose command CAN3_spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_WRITE << 4) + ((address >> 8) & 0xF)); CAN3_spiTransmitBuffer[1] = (uint8_t) (address & 0xFF); // Add data for (CAN3_i = 2; CAN3_i < spiTransferSize; CAN3_i++) {//只看这里!!!!! CAN3_spiTransmitBuffer[CAN3_i] = txd[CAN3_i - 2]; } spiTransferError = CAN3_DRV_SPI_TransferData(index, CAN3_spiTransmitBuffer, CAN3_spiReceiveBuffer, spiTransferSize); return spiTransferError;}从程序第一处 uint16_t spiTransferSize = nBytes + 2;//只看这里!!!!!!中发现spiTransferSize 的值为 spiTransferSize = 96(nBytes )+2,即spiTransferSize =98。观察Debug窗口确实为98:
![]()
再看程序第二处 for (CAN3_i = 2; CAN3_i < spiTransferSize; CAN3_i++) {//只看这里!!!!! CAN3_spiTransmitBuffer[CAN3_i] = txd[CAN3_i - 2]; }是在对大小为96字节的CAN3_spiTransmitBuffer数组进行96次的赋值,for循环从2开始到spiTransferSize,虽然执行了spiTransferSize-2次,即96次,但是却出现了CAN3_spiTransmitBuffer[96],CAN3_spiTransmitBuffer[97]的情况,而CAN3_spiTransmitBuffer数组大小为96字节,最大数组元素为CAN3_spiTransmitBuffer[95],所以数组越界了,越界了2个字节。在.map文件中查看CAN3_spiTransmitBuffer的首地址偏移96个字节就到了下一个变量SensorValue的地址
![]()
但是我们对CAN3_spiTransmitBuffer[96],CAN3_spiTransmitBuffer[97]也赋了值,这两个数据已经超越了CAN3_spiTransmitBuffer管辖范围了,所以就占用了SensorValue数组的前两个字节。所以就会出现我们没对SensorValue数组进行赋值操作内部元素的值却发生了变化:
![]()
|