void UsartThread(const void* args) { DeviceStruct_p DeviceStruct = (DeviceStruct_p) args; usartStruct_p usartDevice = (usartStruct_p) DeviceStruct->Interface->UsartInterface; uint32_t dataCount = 0; // Parser-Funktion setzen parserFunc_p parserFunc = usartDevice->parserFunc; bool isHalfduplex = ((DeviceStruct->Interface->InterfaceType == InterfaceType_Halfduplex) || (DeviceStruct->Interface->InterfaceType == InterfaceType_Modbus_RS485)); if (isHalfduplex) { // Transceiver auf Empfang schalten HAL_GPIO_WritePin(portPin[DeviceStruct->EnablePin].port, portPin[DeviceStruct->EnablePin].pin, GPIO_PIN_RESET); } HAL_UART_Receive_IT(usartDevice->huart, &Usart2RecvDigit, 1); while(1) { osEvent event = osMailGet(usartDevice->mailboxId, osWaitForever); if (event.status == osEventMail) { // Empfang abbrechen / beenden HAL_UART_AbortReceive_IT(usartDevice->huart); usartMailStruct_t usartMail; memcpy(&usartMail, (usartMailStruct_p) event.value.p, sizeof(usartMailStruct_t)); osMailFree(usartDevice->mailboxId, (usartMailStruct_p) event.value.p); if ((usartMail.mailSource == mailSource_recv) && (parserFunc != NULL)) { // Empfangene Daten parsen (Parser schickt ggf. eine Mail z.B mit Quittierung oder Daten an den Thread) parserFunc(usartMail.data, usartMail.dataLength, usartDevice->mailboxId); } else { // Daten über die Schnittstelle ausgeben (Echo, wenn kein Parser gesetzt ist). memcpy(usartDevice->transmitBuffer, &usartMail.data, usartMail.dataLength); dataCount = usartMail.dataLength; } if (isHalfduplex) { // Transceiver auf Senden schalten HAL_GPIO_WritePin(portPin[DeviceStruct->EnablePin].port, portPin[DeviceStruct->EnablePin].pin, GPIO_PIN_SET); } int32_t nSemaphore = osSemaphoreWait(DeviceStruct->Interface->UsartInterface->semaphoreId, 0); while(nSemaphore > 0) { nSemaphore = osSemaphoreWait(DeviceStruct->Interface->UsartInterface->semaphoreId, 0); } // Über die Schnittstelle versenden // HAL_UART_Transmit_DMA(usartDevice->huart, usartDevice->transmitBuffer, dataCount); // HAL_UART_Transmit_IT(usartDevice->huart, usartDevice->transmitBuffer, dataCount); // Auf Semaphore der Callback warten nSemaphore = osSemaphoreWait(DeviceStruct->Interface->UsartInterface->semaphoreId, 500); if (nSemaphore <= 0) { // Fehler (Callback war zu langsam). osDelay(1); } // wieder auf Empfang gehen if (isHalfduplex) { // Transceiver auf Empfang schalten HAL_GPIO_WritePin(portPin[DeviceStruct->EnablePin].port, portPin[DeviceStruct->EnablePin].pin, GPIO_PIN_RESET); } while(HAL_UART_Receive_IT(usartDevice->huart, &Usart2RecvDigit, 1) == HAL_BUSY) { osDelay(10); } } } }