【发布时间】:2017-06-06 04:35:55
【问题描述】:
我正在使用 ATxmega128A1 8 位微控制器,我试图找出为什么我的内存缓冲区行为异常。
我有一个如下结构的 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;
}
我的猜测是我没有安全地在微控制器中分配内存,但是在构建之后,芯片中似乎还有很多内存:
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 通过函数时,地址 0x3FF7 到 0x3FFF 正在改变
编辑 2: Elf Files
【问题讨论】:
-
请提供更多上下文,创建@987654323@。
-
结构有点奇怪。 FIFO(环形缓冲区)一般应该只有一个写点和一个读点。有多个它们有点奇怪。在这种情况下,您不需要“LOCK”机制。
FIFO_Get的代码很容易看到 -
你至少应该发布
FIFO_Get功能代码 -
-添加fifo_get函数
-
510 字节几乎是 0x200(正好是 0x1FE)。你如何分配你的FIFO?作为全局变量,在堆中,在函数栈中?您可能会遇到一些内存限制。
标签: c memory memory-management atmel