Ich möchte den Harmony USART-Treiber auf einem PIC32MX695F512H mit Interrupts und Pufferunterstützung verwenden. Nach dem Setzen der entsprechenden Einstellungen im MPLAB Harmony Configurator hat das System die ISR für mich generiert ( system_interrupt.c
):
void __ISR(_UART_2_VECTOR, ipl1AUTO) _IntHandlerDrvUsartInstance0(void) {
DRV_USART_TasksTransmit(sysObj.drvUsart0);
DRV_USART_TasksReceive(sysObj.drvUsart0);
DRV_USART_TasksError(sysObj.drvUsart0);
}
Da dies eine generierte Datei ist, gehe ich davon aus, dass ich sie nicht bearbeiten soll. Aber wenn dies die ISR ist, wie kann ich sicherstellen, dass mein Code bei einem RX-Interrupt ausgeführt wird? Ich möchte die empfangenen Daten in einer Funktion erhalten, die ich bearbeiten soll.
So wie ich es verstehe, ist das der Buffer-Event-Handler. Ich kann also Folgendes tun (dieser Code ist stark vereinfacht):
void APP_BufferEventHandler(DRV_USART_BUFFER_EVENT bufferEvent,
DRV_USART_BUFFER_HANDLE bufferHandle, uintptr_t context) {
switch (bufferEvent) {
case DRV_USART_BUFFER_EVENT_COMPLETE:
// @todo
break;
case DRV_USART_BUFFER_EVENT_ERROR:
appData.state = APP_ERROR;
break;
case DRV_USART_BUFFER_EVENT_ABORT:
appData.state = APP_ERROR;
break;
}
}
//... in APP_Tasks somewhere:
appData.usartHandle = DRV_USART_Open(DRV_USART_INDEX_0,
DRV_IO_INTENT_READWRITE | DRV_IO_INTENT_NONBLOCKING);
DRV_USART_BufferEventHandlerSet(appData.usartHandle,
APP_BufferEventHandler, 0);
Meine Fragen sind:
APP_BufferEventHandler
dass bei einem RX-Interrupt aufgerufen wird?COMPLETE
, ERROR
und ist ABORT
?Sie haben ziemlich genau ihr beabsichtigtes Modell richtig. Um Ihre Fragen zu beantworten:
Wenn Sie sich ihr Abstraktionsmodell unten ansehen, würden Sie den Kontextparameter verwenden , um festzustellen, auf welchen Client im Ereignishandler verwiesen wird, da mehrere Clients dieselbe USART-Hardware gemeinsam nutzen können.
Unten ist einer ihrer Buffer Event Handler in ihrem USART-Treiberbeispiel. Sie können sehen, dass sie sowohl den Kontextparameter bestätigen als auch, wo ihre USART-Aufgaben-Zustandsmaschine das Ereignis behandeln und die Zustandsmaschine weiterbewegen soll.
C:\microchip\harmony\v1_06_02\apps\driver\usart\usart_loopback\firmware
void APP_BufferEventHandlerUsart1(DRV_USART_BUFFER_EVENT buffEvent,
DRV_USART_BUFFER_HANDLE hBufferEvent,
uintptr_t context )
{
switch(buffEvent)
{
/* Buffer event is completed successfully */
case DRV_USART_BUFFER_EVENT_COMPLETE:
{
if((context == 1) &&(appData.usart1State == APP_STATE_USART1_WAIT_FOR_TX_COMPLETION))
{
appData.usart1State = APP_STATE_USART1_WAIT_TO_RX_BACK_DATA;
}
else if((context == 1) &&(appData.usart1State == APP_STATE_USART1_WAIT_TO_RX_BACK_DATA))
{
gDataRxedAtUsart1 = true;
appData.state = APP_STATE_VERIFY_LOOPBACK_DATA;
}
}
break;
/* Buffer event has some error */
case DRV_USART_BUFFER_EVENT_ERROR:
break;
default:
break;
}
}
Es ist (meiner Meinung nach) schwer zu rechtfertigen, wie komplex es ist, Harmony für irgendetwas anderes als einen riesigen Multitasking-Giganten zum Laufen zu bringen. Wenn Sie jedoch viele Objekte haben, die sich viele Ressourcen teilen, kann es sich lohnen, Harmony auszuprobieren.
Meiner Meinung nach müssen Sie tatsächlich Code in der __ISR hinzufügen. Zum Beispiel:
void __ISR(_UART_1_VECTOR, ipl1AUTO) _IntHandlerDrvUsartInstance0(void) {
DRV_USART_TasksTransmit(sysObj.drvUsart0);
DRV_USART_TasksReceive(sysObj.drvUsart0);
DRV_USART_TasksError(sysObj.drvUsart0);
//o_LED_ld3 = ~o_LED_ld3;
while (!DRV_USART_ReceiverBufferIsEmpty(appData.UsartHandle))
{
// read received byte
appData.rx_byte = DRV_USART_ReadByte(appData.UsartHandle);
//UART_Write_Char(appData.rx_byte);
}
}
Benutzer17592
Edesign