Ich versuche, ein Flag zu verwenden, um zu sehen, ob ein Ereignis beendet ist. Über den Debugger habe ich gesehen, dass der Interrupt korrekt ausgelöst wird und den Wert transmitCompleteI2c
auf 1 setzt. Wenn ich zur if-Anweisung zurückkehre, die prüft, ob das Flag auf 1 gesetzt wurde oder nicht, wurde es zurückgesetzt zu 0.C++ - Variable geändert während Interrupt zurückgesetzt nach Interrupt
Die einzigen 2 Orte, wo ich den Wert von transmitCompleteI2c
ändern, sind nach der if-Anweisung und in der Interrupt-Routine.
Ich führe die folgenden Bits Code. Die Deklaration von transmitCompleteI2c
erfolgt in der Header-Datei der Klasse. fireEvent()
ist eine Mitgliedsfunktion der Klasse I2c
.
volatile uint8_t transmitCompleteI2c;
void I2c::foo() {
if (transmitCompleteI2c) {
transmitCompleteI2c = 0;
// trigger event which sets transmitComplete back to 0 when done
fireEvent();
}
}
void I2c::sendHandler(XIic *InstancePtr) {
transmitCompleteI2c = 1;
}
Nach einiger umfangreichen Graben, es stellte sich heraus, dass die Adresse der Interrupt-Routine ein transmitCompleteI2c
schreibt nicht die gleiche wie die Variable in der Klasse ist. Auch nach dem Umbenennen der Variablen passiert es immer noch. Im Folgenden finden Sie die Header-Datei und den Quellcode meiner Klasse.
Headerdatei:
#define SLAVE_ADDRESS 0xA0/2
#define SEND_COUNT 16
#define RECEIVE_COUNT 16
#define IIC_INTR_ID XPAR_FABRIC_AXI_IIC_0_IIC2INTC_IRPT_INTR
#define IIC_DEVICE_ID XPAR_AXI_IIC_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
class I2c{
private:
void sendHandler(void* InstancePtr, int);
void receiveHandler(XIic* InstancePtr, int);
void statusHandler(XIic* InstancePtr, int);
XIic_Config* configPtr;
const XScuGic& intcInterrupt;
XIic iicDevice;
int status;
uint8_t writeBuffer[SEND_COUNT];
uint8_t readBuffer[RECEIVE_COUNT];
volatile uint8_t transmitCompleteI2c, receiveComplete;
volatile bool test;
public:
I2c() : intcInterrupt{IntcInstance} {};
uint8_t initialize();
int writeData(u16 ByteCount);
int readData(u8 *BufferPtr, u16 ByteCount);
};
Implementierung: Initialisierung Funktion:
uint8_t I2c::initialize() {
// init driver
configPtr = XIic_LookupConfig(IIC_DEVICE_ID);
XIic_CfgInitialize(&iicDevice, configPtr, configPtr->BaseAddress);
//init interrupt system
XScuGic_SetPriorityTriggerType((XScuGic*) &intcInterrupt, IIC_INTR_ID, 0xA0, 0x3);
status = XScuGic_Connect((XScuGic*) &intcInterrupt, IIC_INTR_ID, (Xil_ExceptionHandler) XIic_InterruptHandler, &iicDevice);
XScuGic_Enable((XScuGic*) &intcInterrupt, IIC_INTR_ID);
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, (Xil_ExceptionHandler) XScuGic_InterruptHandler, &IntcInstance);
Xil_ExceptionEnable();
// set transmit flag
transmitCompleteI2c = true;
xil_printf("%08x\n", &transmitCompleteI2c);
// attach interrupts to i2c device
XIic_SetSendHandler(&iicDevice, &iicDevice, (XIic_Handler) (&I2c::sendHandler));
XIic_SetRecvHandler(&iicDevice, &iicDevice, (XIic_Handler) &I2c::receiveHandler);
XIic_SetStatusHandler(&iicDevice, &iicDevice, (XIic_StatusHandler) &I2c::statusHandler);
// set slave address
status = XIic_SetAddress(&iicDevice, XII_ADDR_TO_SEND_TYPE, SLAVE_ADDRESS);
// start device
status = XIic_Start(&iicDevice);
if (status != XST_SUCCESS) {
return XST_FAILURE;
}
return 0;
}
Daten schreiben Funktion:
int I2c::writeData(u16 ByteCount) {
xil_printf("%08x\n", &transmitCompleteI2c);
/*
* Set flag
*/
transmitCompleteI2c = false;
/*
* Send the data
*/
status = XIic_MasterSend(&iicDevice, &writeBuffer[0], 6);
if (status != XST_SUCCESS) {
xil_printf("%d\n", status);
return XST_FAILURE;
}
return XST_SUCCESS;
}
Interrupt-Routine:
void I2c::sendHandler(void *InstancePtr, int byteCount) {
transmitCompleteI2c = true;
xil_printf("%08x\n", &transmitCompleteI2c);
}
Warum verwenden Sie invertierte Logik für sendeComplete? Wäre es nicht sinnvoller, es als bool zu deklarieren und nach Abschluss der Übertragung auf wahr zu setzen? Natürlich hilft das nicht wirklich bei deinem Problem, aber trotzdem ... –
@ H.Guijt Ja, das stimmt. Ändern Sie es in der Frage und Code für bessere Lesbarkeit – Etruscian
Dieser Teil des Codes zeigt sich nicht mit evedence, ist dieser Thread sicher? Eine solche Verwendung von Variablen provoziert Gefahren. –