gpt4 book ai didi

C 内存缓冲区破坏微 Controller 内存分配 - Atmel ATxmega

转载 作者:行者123 更新时间:2023-11-30 14:56:51 26 4
gpt4 key购买 nike

我正在使用 ATxmega128A1 8 位微 Controller ,我试图找出为什么我的内存缓冲区表现异常。

我有一个具有以下结构的 FIFO 缓冲区:

typedef struct
{
FIFOid ID; //ID value to determine the type of FIFO being used
BOOL LOCK; //A lock to prevent multiple FIFO accessing (i.e. data corruption)
UINT16 Start, End; //Value of the current start and end FIFO index
UINT16 volatile NbBytes; //Number of bytes currently inside the FIFO
UINT8 Buffer[FIFO_SIZE]; //Memory buffer for the FIFO buffer
} TFIFO;

我定义了 2 个 FIFO:

//FIFO Buffers for USART
TFIFO RxFIFO; //Creates the Receive FIFO
TFIFO TxFIFO; //Creates the Transmit FIFO

FIFO_SIZE 的位置

#define FIFO_SIZE 256       

当我想从 Buffer[] 获取一个字节时,我通过此函数传递一个指向 FIFO 的指针:

BOOL FIFO_Get(TFIFO * const FIFO, UINT8 * const dataPtr);

但是,一旦我将 FIFO_SIZE 增加到约 510 字节以上,此方法就可以正常工作 - 通过此函数传递此 FIFO 指针会导致我的另一个 FIFO 缓冲区发生更改。

我在我的调试器上看到,这一行没有问题:

if(FIFO_Get(&TxFIFO, &data)){       //Get a byte from TxFIFO

一旦我跨过,并将其传递给函数,RxFIFO->Buffer[] 数组就会被修改,即较大的地址值。FIFO_Get函数:

// ----------------------------------------
// FIFO_Get
// ----------------------------------------
// Remove one character from the FIFO
// Input:
// FIFO is a pointer to a FIFO struct with data to be retrieved
// dataPtr is a pointer to a memory location to place the retrieved byte
// Output:
// TRUE if the operation was successful and the data is valid
// Conditions:
// Assumes that FIFO_Init has been called

BOOL FIFO_Get(TFIFO * const FIFO, UINT8 * const dataPtr)
{
BOOL FIFOGetSuccess;
FIFOGetSuccess = bFALSE;

//disable interrupts
//if we're GETTING from the USART receive FIFO
//we need to disable the receive interrupt so
//there is no data being 'Put' during a 'Get'
if(FIFO->ID == URX){
USARTD0.CTRLA = USART_RXCINTLVL_OFF_gc; //Rx interrupts off
USARTD1.CTRLA = USART_RXCINTLVL_OFF_gc; //Rx interrupts off
}

//Attempt to get a byte from the FIFO
if(FIFO->LOCK == bFALSE){ //Check that the FIFO is not locked
FIFO->LOCK = bTRUE; //lock the FIFO
if (FIFO->NbBytes == 0){ //Checks whether FIFO is empty; number of bytes in FIFO = 0
FIFOGetSuccess = bFALSE; //If empty, false is Returned
}else{
*dataPtr = FIFO->Buffer[FIFO->Start]; //Reads the byte in the FIFO start position, and saves it to the location of the data pointer
if (FIFO->Start == (FIFO_SIZE - 1)){ //Checks whether the start position is equal to FIFO size, the last valid 8 bit number
FIFO->Start = 0; //If so, the position is set to 0
}else{ //If not fifo size;
FIFO->Start++; //Increments the start position by 1
}
FIFO->NbBytes--; //Decrements the number of bytes in the FIFO by 1
FIFOGetSuccess = bTRUE; //Returns true if this is successful
}
FIFO->LOCK = bFALSE; //unlock the FIFO
}

//re-enable interrupts
if(FIFO->ID == URX){
USARTD0.CTRLA = USART_RXCINTLVL_LO_gc; //low level interrupts on Rx
USARTD1.CTRLA = USART_RXCINTLVL_LO_gc; //low level interrupts on Rx
}

return FIFOGetSuccess;
}

我的猜测是,我没有在微 Controller 中安全地分配内存,但是在构建之后,芯片中似乎还留有足够的内存:

        Program Memory Usage    :   21460 bytes   15.4 % Full
Data Memory Usage : 6967 bytes 12.1 % Full

我该如何解决这个问题以及我做错了什么?

编辑:

我发现增加 FIFO SIZE 会将 FIFO 缓冲区映射到 SRAM 地址范围(ATxmega128A1 的 SRAM 从 0x2000 到 0x3FFF)

FIFO address mapping

当另一个 FIFO 通过函数传递时,地址 0x3FF7 到 0x3FFF 正在发生变化

编辑2: Elf Files

最佳答案

从ELF文件中,我可以看到这个内存映射:

00802000 B __bss_start
00802000 D __data_end
00802000 D __data_start
00802000 D _edata
00802000 00000002 b n.4418
00802002 00000001 b packetEnd.1686
00802003 00000002 b byteCount.1684
00802005 00000002 b StepsCounted.4253
00802007 00000001 b ErrorCode.4252
00802008 00000001 b SuccessNb.4251
00802009 00000001 b ReturnNb.4250
0080200a 00000004 b stepsOutOpto.4211
0080200e 00000004 b HomingError.4212
00802012 00000008 b stepscounted.4210
0080201a 00000004 b CntHomeState.4209
0080201e 00000001 b byteCount.4166
0080201f 00000002 B EjectMsgID
00802021 00000001 B VersionMinor
00802022 00000002 B QueueEnd
00802024 00000001 B VersionMonth
00802025 00000001 B ACC1_IN
00802026 0000001f B PacketQRx
00802045 0000001f B PacketTx
00802064 00000001 B VersionMajor
00802065 00000001 B DeviceTypeId
00802066 00000001 B debugCycler_bytes
00802067 00000001 B debugAXIS_ACK
00802068 000000d4 B AXIS
0080213c 00000001 B LVL_SENSE_IN
0080213d 00000001 B LID_DETECTION_ON
0080213e 00000001 B readyimmediateTx
0080213f 0000001f B PacketQTx
0080215e 00000004 B RobotSerialNumber
00802162 00000001 B USBIN
00802163 00000001 B startupComplete
00802164 000007c0 B PacketQueue
00802924 0000001f B PacketRx
00802943 00000001 B ACC2_IN
00802944 00000002 B QueueNb
00802946 00000001 B QueuedCommandCalled
00802947 0000001f B dummyPkt
00802966 00000001 B CYCLER_IN
00802967 00000002 B QueueStart
00802969 00000001 B HardwareRevision
0080296a 00000001 B VersionYear
0080296b 00000980 B AXISRxFIFO
008032eb 00000004 B RTS
008032ef 00000980 B AXISTxFIFO
00803c6f 00000068 B AXIS_SPI_Tx_Packet
00803cd7 00000004 B ReturnPacketMissed
00803cdb 00000068 B AXIS_SPI_Rx_Packet
00803d43 00000004 B NbPacketsInAxisFIFO
00803d47 00000100 B CyclerEEPROM
00803e47 00000260 B TxFIFO
008040a7 00000260 B RxFIFO
00804307 B __bss_end

注意:我获得此 map 的方式是使用 nm 和命令 nm -S -n MotorBoard\Xmega\Large\FIFO.elf。第一列是地址,第二列是变量的大小。

ATMEL ATxmega128A1 Datasheet表示您在 0x20000x3FFF 之间有 8KB SRAM。正如您所看到的,您的两个 FIFO 缓冲区都重叠了 0x3FFF 限制(TxFIFO0x3E470x40A7 >RxFIFO)。

解决问题的一种方法是将某些变量声明为 const,将其移至 ROM 中。例如,我可以看到 VersionMonthVersionMajor 可能是恒定的。

关于C 内存缓冲区破坏微 Controller 内存分配 - Atmel ATxmega,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44381487/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com