Hi folks, I have started using KSDK 1.1.0 with the TWR-K60D100M. I can build and run the "hello world" demo without problem, but it seems that getchar() exhibits non-standard behavior. Instead of returning EOF if no character is available, it blocks.
I'm using the IAR 7.40.2 ARM tools for Cortex-M. I'm not using MQX or any other RTOS. The application I will be developing is a "bare metal" super-loop.
I think the offending area in the KSDK code is in the implementation of _read(), in fsl_debug_console.c. Here it is:
#pragma weak __read
size_t __read(int handle, unsigned char * buffer, size_t size)
{
/* This function only reads from "standard in", for all other file*/
/* handles it returns failure.*/
if (handle != _LLIO_STDIN)
{
return _LLIO_ERROR;
}
/* Do nothing if the debug uart is not initialized.*/
if (s_debugConsole.type == kDebugConsoleNone)
{
return _LLIO_ERROR;
}
/* Receive data.*/
s_debugConsole.ops.rx_union.Receive(s_debugConsole.baseAddr, buffer, size);
return size;
}
The Receive() function above in turn calls UART_HAL_ReceiveDataPolling(), from fsl_uart_hal.c. Here's the code:
uart_status_t UART_HAL_ReceiveDataPolling(uint32_t baseAddr,
uint8_t *rxBuff,
uint32_t rxSize)
{
uart_status_t retVal = kStatus_UART_Success;
while (rxSize--)
{
while (!UART_HAL_IsRxDataRegFull(baseAddr))
{}
UART_HAL_Getchar(baseAddr, rxBuff++);
/* Clear the Overrun flag since it will block receiving */
if (BR_UART_S1_OR(baseAddr))
{
HW_UART_S1_RD(baseAddr);
HW_UART_D_RD(baseAddr);
retVal = kStatus_UART_RxOverRun;
}
}
return retVal;
}
The loop while (!UART_HAL_ISRxDataRegFull(baseAddr)) guarantees that this function won't return until a character is actually received. According to all the C references I have read, it _should_ return an EOF is there isn't a character available. That way the code could poll for a character, and if it gets EOF, just skip to the next step in my super-loop.
In pseudocode, something like this:
while (1)
{
int c;
while ((c = getchar()) != EOF)
{
// Add the character to an input buffer
// See if it's the end of the line
// If so, parse the line and decide what command to execute
}
RunTask1(); // Functions that perform some kind of ongoing action, like reading ADC values, scanning GPIO lines, etc.
RunTask2();
// etc.
}
Have any of you run into this situation? How did you keep getchar() from blocking? I could rewrite the _read() function to do what I need, but I'm a little surprised at the default behavior of the fsl_debug_console.
As a next step, I would like to run the UART transmit and receive in interrupt-driven mode to avoid polling altogether, perhaps only checking to see if an entire input line has been received. Do any of you have examples of how to set up a UART in interrupt mode with buffers for transmit and receive? And down the line, there will be two UARTs, one that accepts commands from a PC and one to dump out debug information (and maybe accept some simple debug commands).
Many thanks for your help!