288 lines
8.0 KiB
C
288 lines
8.0 KiB
C
/*********************************************************************
|
|
* (c) SEGGER Microcontroller GmbH *
|
|
* The Embedded Experts *
|
|
* www.segger.com *
|
|
**********************************************************************
|
|
|
|
-------------------------- END-OF-HEADER -----------------------------
|
|
Purpose : Implementation of low-level functions for I/O with the
|
|
SEGGER Runtime Library
|
|
using a UART (SEGGER's BSP UART module)
|
|
*/
|
|
|
|
/*********************************************************************
|
|
*
|
|
* #include section
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
#include "__SEGGER_RTL_Int.h"
|
|
#include "stdio.h"
|
|
#include "Bsp.h"
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Local types
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
struct __SEGGER_RTL_FILE_impl { // NOTE: Provides implementation for FILE
|
|
int stub; // only needed so impl has size != 0.
|
|
};
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Static data
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
static FILE __SEGGER_RTL_stdin_file = { 0 }; // stdin reads from UART
|
|
static FILE __SEGGER_RTL_stdout_file = { 0 }; // stdout writes to UART
|
|
static FILE __SEGGER_RTL_stderr_file = { 0 }; // stderr writes to UART
|
|
|
|
static unsigned int _UART_Port = TTY_COM;
|
|
static int _stdin_ungot = EOF;
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Public data
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
FILE *stdin = &__SEGGER_RTL_stdin_file; // NOTE: Provide implementation of stdin for RTL.
|
|
FILE *stdout = &__SEGGER_RTL_stdout_file; // NOTE: Provide implementation of stdout for RTL.
|
|
FILE *stderr = &__SEGGER_RTL_stderr_file; // NOTE: Provide implementation of stderr for RTL.
|
|
|
|
|
|
void *__aeabi_read_tp(void) {
|
|
return 0; // 单线程环境下直接返回 0
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Static code
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _stdin_getc()
|
|
*
|
|
* Function description
|
|
* Get character from standard input.
|
|
*
|
|
* Return value
|
|
* Character received.
|
|
*
|
|
* Additional information
|
|
* This function never fails to deliver a character.
|
|
*/
|
|
static char _stdin_getc(void) {
|
|
unsigned char c;
|
|
|
|
if (_stdin_ungot != EOF) {
|
|
c = _stdin_ungot;
|
|
_stdin_ungot = EOF;
|
|
} else {
|
|
c = UsartReceiveChar(_UART_Port);
|
|
}
|
|
return c;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Public code
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
/*********************************************************************
|
|
*
|
|
* RTL_UART_Init()
|
|
*
|
|
* Function description
|
|
* Initialize RTL to use given UART for stdio.
|
|
*
|
|
* Parameters
|
|
* Unit : UART unit number (typically zero-based).
|
|
* Baudrate : Baud rate to configure [Hz].
|
|
* NumDataBits: Number of data bits to use.
|
|
* Parity : One of the following values:
|
|
* * BSP_UART_PARITY_NONE
|
|
* * BSP_UART_PARITY_ODD
|
|
* * BSP_UART_PARITY_EVEN
|
|
* NumStopBits: Number of stop bits to use.
|
|
*
|
|
* Additional description
|
|
* Parameters are same as for BSP_UART_Init().
|
|
* This also sets appropriate RX and TX interrupt handlers.
|
|
*/
|
|
void RTL_UART_Init(unsigned int Unit, unsigned long Baudrate, unsigned char NumDataBits, unsigned char Parity, unsigned char NumStopBits) {
|
|
_UART_Port = Unit;
|
|
UsartStdConfig(_UART_Port, Baudrate);
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* __SEGGER_RTL_X_file_stat()
|
|
*
|
|
* Function description
|
|
* Get file status.
|
|
*
|
|
* Parameters
|
|
* stream - Pointer to file.
|
|
*
|
|
* Additional information
|
|
* Low-overhead test to determine if stream is valid. If stream
|
|
* is a valid pointer and the stream is open, this function must
|
|
* succeed. If stream is a valid pointer and the stream is closed,
|
|
* this function must fail.
|
|
*
|
|
* The implementation may optionally determine whether stream is
|
|
* a valid pointer: this may not always be possible and is not
|
|
* required, but may assist debugging when clients provide wild
|
|
* pointers.
|
|
*
|
|
* Return value
|
|
* < 0 - Failure, stream is not a valid file.
|
|
* >= 0 - Success, stream is a valid file.
|
|
*/
|
|
int __SEGGER_RTL_X_file_stat(FILE *stream) {
|
|
if (stream == stdin || stream == stdout || stream == stderr) {
|
|
return 0; // NOTE: stdin, stdout, and stderr are assumed to be valid.
|
|
} else {
|
|
return EOF;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* __SEGGER_RTL_X_file_bufsize()
|
|
*
|
|
* Function description
|
|
* Get stream buffer size.
|
|
*
|
|
* Parameters
|
|
* stream - Pointer to file.
|
|
*
|
|
* Additional information
|
|
* Returns the number of characters to use for buffered I/O on
|
|
* the file stream. The I/O buffer is allocated on the stack
|
|
* for the duration of the I/O call, therefore this value should
|
|
* not be set arbitrarily large.
|
|
*
|
|
* For unbuffered I/O, return 1.
|
|
*
|
|
* Return value
|
|
* Nonzero number of characters to use for buffered I/O; for
|
|
* unbuffered I/O, return 1.
|
|
*/
|
|
int __SEGGER_RTL_X_file_bufsize(FILE *stream) {
|
|
(void)stream;
|
|
return 1;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* __SEGGER_RTL_X_file_read()
|
|
*
|
|
* Function description
|
|
* Read data from file.
|
|
*
|
|
* Parameters
|
|
* stream - Pointer to file to read from.
|
|
* s - Pointer to object that receives the input.
|
|
* len - Number of characters to read from file.
|
|
*
|
|
* Return value
|
|
* >= 0 - Success, amount of data read.
|
|
* < 0 - Failure.
|
|
*
|
|
* Additional information
|
|
* Reading from any stream other than stdin results in an error.
|
|
*/
|
|
int __SEGGER_RTL_X_file_read(FILE *stream, char *s, unsigned len) {
|
|
int c;
|
|
|
|
if (stream == stdin) {
|
|
c = 0;
|
|
while (len > 0) {
|
|
*s = _stdin_getc();
|
|
++s;
|
|
++c;
|
|
--len;
|
|
}
|
|
} else {
|
|
c = EOF;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* __SEGGER_RTL_X_file_write()
|
|
*
|
|
* Function description
|
|
* Write data to file.
|
|
*
|
|
* Parameters
|
|
* stream - Pointer to file to write to.
|
|
* s - Pointer to object to write to file.
|
|
* len - Number of characters to write to the file.
|
|
*
|
|
* Return value
|
|
* >= 0 - Success.
|
|
* < 0 - Failure.
|
|
*
|
|
* Additional information
|
|
* this version is NOT reentrant!
|
|
* stdout and stderr are directed to UART;
|
|
* writing to any stream other than stdout or stderr results in an error
|
|
*/
|
|
int __SEGGER_RTL_X_file_write(FILE *stream, const char *s, unsigned len) {
|
|
if ((stream == stdout) || (stream == stderr)) {
|
|
UsartSendStr(_UART_Port, (uint8_t* ) s, len);
|
|
return len;
|
|
} else {
|
|
return EOF;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* __SEGGER_RTL_X_file_unget()
|
|
*
|
|
* Function description
|
|
* Push character back to stream.
|
|
*
|
|
* Parameters
|
|
* stream - Pointer to file to push back to.
|
|
* c - Character to push back.
|
|
*
|
|
* Return value
|
|
* >= 0 - Success.
|
|
* < 0 - Failure.
|
|
*
|
|
* Additional information
|
|
* Push-back is only supported for standard input, and
|
|
* only a single-character pushback buffer is implemented.
|
|
*/
|
|
int __SEGGER_RTL_X_file_unget(FILE *stream, int c) {
|
|
if (stream == stdin) {
|
|
if (c != EOF && _stdin_ungot == EOF) {
|
|
_stdin_ungot = c;
|
|
} else {
|
|
c = EOF;
|
|
}
|
|
} else {
|
|
c = EOF;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
/*************************** End of file ****************************/ |