Hello,
I'm implementing UART reading from a device based on STM32F469
I'm using DMA and the peripheral works, when the DMA buffer is full, the call to HAL_UART_RxCpltCallback sends back to have a feedback and it doesn't miss a char.
So i know i have the data in the buffer available.
I made a flag to stop writing on that buffer when the message is not still processed by the GUI.
Following the Device integration Example, i made a init function for the UART thred to continously print whats on the buffer, this init is called in the Init() of the Device instance in Embedded Wizard.
void Uart_Thread_Init( void )
{
/* check for initialization */
if ( DeviceInitialized )
return;
/*init delle funzioni*/
DeviceInitialized = 1;
#if EW_USE_OPERATING_SYSTEM == 1
/* create and start the worker thread to process UART data */
WorkerThread = EwBspOsThreadCreate( UartWorkerThread, EW_BSP_OS_THREAD_PRIORITY_NORMAL, 1024, 0 );
#endif
}
This is the worker thread i made, the function SIN_GetCharacter() only makes a call to the function HAL_UART_Receive_DMA (&huart6, data, 10), which writes in a 10 bytes array called data.
static void UartWorkerThread( const void* arg)
{
SIN_GetCharacter();
while ( DeviceInitialized )
{
if(newMessage==1)
{
EwInvokeCopy( UpdateUartCharProc, &data, sizeof(data));
}
/* sleep for a certain period... */
EwBspOsDelay( 20 );
}
/* terminate the worker thread */
WorkerThread = 0;
EwBspOsThreadDestroy( EwBspOsThreadGetHandle());
}
The process method UpdateUartCharProc to update the GUI is the following:
static void UpdateUartCharProc( const void* aData )
{
char* uartChar = (char *)aData;
/* only in case that the device driver is still initialized and the worker
thread is still running, the data should be provided to the device class
- otherwise, a new autoobject will be created and a new worker thread
started... */
if ( DeviceInitialized )
{
for(int i = 0 ; i <sizeof(uartChar); i++)
{
if ((( uartChar[i] >= 'A' ) && ( uartChar[i] <= 'Z' )) || (( uartChar[i] >= 'a' ) && ( uartChar[i] <= 'z' ))
|| (( uartChar[i] >= '0' ) && ( uartChar[i] <= '9' )) || ( uartChar[i] == ' ' ))
{
ApplicationDeviceClass device = EwGetAutoObject( &ApplicationDevice, ApplicationDeviceClass );
ApplicationDeviceClass__TCPMessageUpdate( device, uartChar[i] );
}
}
newMessage=0;
SIN_GetCharacter();
}
}
I arrived at this point from various conclusions:
1 - The data is available from the UART so the data buffer is correct.
2 - Calling EwInvokecopy from the uart callback seems to be too slow to process the data to the GUI.
3 - the newMessage flag is used to stop the buffer modification until all the char are sent to the gui, it is updated after all the char from the new message are processed
4 - tried to pass directly the array of char to the UpdateCharProc instead of single char with EwInvokecopy, don't konw if the code is correct.
5 - if i sent a "0123456789" i get printed only the fourth char.