Я создал обработчик (структуру), чтобы иметь интерфейс для EUSART, который не зависит от фактического номера EUSART.
Вот код API шины:
// Type definitions
typedef uint8_t (*EUSART_Read_Func)(void);
typedef uint8_t (*EUSART_LastStatus_Func)(void);
typedef uint8_t (*EUSART_get_RXCount)(void);
typedef struct {
EUSART_Read_Func pxRead;
EUSART_LastStatus_Func pxLastStatus;
EUSART_get_RXCount pxRXCount;
uint8_t ucFramePointer;
uint8_t ucChecksum;
volatile uint8_t *pxPingBuffer;
volatile uint8_t *pxPongBuffer;
volatile uint8_t *pxCurrentFrameBuffer;
uHMPBusRXStatus uRXStatus;
}xHMPBusHandler;
// Global variables
volatile uint8_t ucHMPBus1FrameBufferPing[BUFFSIZE];
volatile uint8_t ucHMPBus1FrameBufferPong[BUFFSIZE];
volatile xHMPBusHandler xHMPBus1Handler;
//APIs
void vHMPBusInit (void) {
// Use EUSART1
xHMPBus1Handler.pxLastStatus = EUSART1_get_last_status;
xHMPBus1Handler.pxRXCount = EUSART1_get_RXCount;
xHMPBus1Handler.pxRead = EUSART1_Read;
// Initialize Bus 1 handler
xHMPBus1Handler.ucChecksum = 0;
xHMPBus1Handler.uRXStatus.usStatus = CLEAR;
xHMPBus1Handler.ucFramePointer = 0;
xHMPBus1Handler.pxPingBuffer = ucHMPBus1FrameBufferPing;
xHMPBus1Handler.pxPongBuffer = ucHMPBus1FrameBufferPong;
xHMPBus1Handler.pxCurrentFrameBuffer = xHMPBus1Handler.pxPingBuffer;
}
volatile uint8_t *pxTestPointer;
// Get the data from the EUSART
void vHMPBusGetData( volatile xHMPBusHandler * puBus ) {
uint8_t ucData;
eusart1_RXstatus_t xLastStatus;
uint8_t ucRXCount;
// Get number of byte in the communication buffer
ucRXCount = puBus->pxRXCount();
// Get all byte currently in the communication buffer
while (ucRXCount)
{
// Read 1 byte from the communication buffer and acquire its status
ucData = puBus->pxRead();
// Some code left out of this example
// Store the received byte in the HMP bus buffer
if ( puBus->uRXStatus.HMPBufferOverflow ) {
return;
} else {
puBus->pxCurrentFrameBuffer[puBus->ucFramePointer++] = ucData;
}
// Select buffer
if (puBus->uRXStatus.PingFull) {
puBus->pxCurrentFrameBuffer = puBus->pxPingBuffer;
} else {
pxTestPointer = puBus->pxPongBuffer;
puBus->pxCurrentFrameBuffer = ucTest;
}
// Check if full frame has been received
if (puBus->ucFramePointer >= FRAMESIZE)
{
if (puBus->pxCurrentFrameBuffer == puBus->pxPingBuffer)
puBus->uRXStatus.PingFull = true;
else
puBus->uRXStatus.PongFull = true;
}
}
}
Это основной код, вызывающий функции API:
void main(void) {
// initialize
vHMPBusInit ();
// Enable the Global- and Peripheral Interrupts
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
while (1) {
vHMPBusGetData(&xHMPBus1Handler);
}
}
Все начинает казаться мне странным в следующих строках кода:
// Select buffer
if (puBus->uRXStatus.PingFull) {
puBus->pxCurrentFrameBuffer = puBus->pxPingBuffer;
} else {
// Test to see what happens with indirect copy of pointer
pxTestPointer = puBus->pxPongBuffer;
puBus->pxCurrentFrameBuffer = pxTestPointer;
puBus->pxCurrentFrameBuffer = puBus->pxPongBuffer;
}
После отладки я заметил что-то странное. Копирование указателя на PingBuffer (на который ссылается puBus) непосредственно в pxCurrentFrameBuffer, привело к неожиданному адресу, хранящемуся в pxCurrentFrameBuffer.
Когда я пытаюсь сделать это косвенно, как проверено в части кода ELSE, используя pxTestPointer, адрес копируется из pxPongBuffer в pxTestPointer и рядом с pxCurrentFrameBuffer, как и ожидалось.
Что мне не хватает?
Любая помощь будет принята с благодарностью.
Gr. Майк
Я также приложил просмотры памяти и листинг дизассемблера
! pxTestPointer = puBus->pxPongBuffer;
0x13D: MOVF ucCRCHi, W
0x13E: ADDLW 0x9
0x13F: MOVWF FSR1
0x140: CLRF FSR1H
0x141: MOVF INDF1, W
0x142: MOVWF pxTestPointer
0x143: MOVLW 0x1
0x144: MOVWF 0x3F
! puBus->pxCurrentFrameBuffer = pxTestPointer;
0x145: MOVF ucCRCHi, W
0x146: ADDLW 0xA
0x147: MOVWF FSR1
0x148: CLRF FSR1H
0x149: MOVF pxTestPointer, W
0x14A: MOVWI 0[FSR1]
0x14B: MOVF 0x3F, W
0x14C: MOVWI 1[FSR1]
! puBus->pxCurrentFrameBuffer = puBus->pxPongBuffer;
0x14D: MOVF ucCRCHi, W
0x14E: ADDLW 0x9
0x14F: MOVWF FSR1
0x150: CLRF FSR1H
0x151: MOVF ucCRCHi, W
0x152: ADDLW 0xA
0x153: MOVWF FSR0
0x154: CLRF FSR0H
0x155: MOVF FSR1, W
0x156: MOVWI 0[FSR0]
0x157: MOVLW 0x1
0x158: MOVWI 1[FSR0]
После инициализации:
After copy using pxTestPointer:
After direct copy:
После прямой копии