/***************************************************************************//** * @file * @brief Provide stdio retargeting for all supported toolchains. * @version 5.5.0 ******************************************************************************* * # License * Copyright 2015 Silicon Labs, Inc. http://www.silabs.com ******************************************************************************* * * This file is licensed under the Silabs License Agreement. See the file * "Silabs_License_Agreement.txt" for details. Before using this software for * any purpose, you must agree to the terms of that agreement. * ******************************************************************************/ /***************************************************************************//** * @addtogroup RetargetIo * @{ This module provide low-level stubs for retargetting stdio for all * supported toolchains. * The stubs are minimal yet sufficient implementations. * Refer to chapter 12 in the reference manual for newlib 1.17.0 * for details on implementing newlib stubs. ******************************************************************************/ extern int RETARGET_ReadChar(void); extern int RETARGET_WriteChar(char c); #if !defined(__CROSSWORKS_ARM) && defined(__GNUC__) #include #include #include #include #include "em_device.h" /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ int fileno(FILE *); /** @endcond */ int _close(int file); int _fstat(int file, struct stat *st); int _isatty(int file); int _lseek(int file, int ptr, int dir); int _read(int file, char *ptr, int len); caddr_t _sbrk(int incr); int _write(int file, const char *ptr, int len); extern char _end; /**< Defined by the linker */ /**************************************************************************//** * @brief * Close a file. * * @param[in] file * File you want to close. * * @return * Returns 0 when the file is closed. *****************************************************************************/ int _close(int file) { (void) file; return 0; } /**************************************************************************//** * @brief Exit the program. * @param[in] status The value to return to the parent process as the * exit status (not used). *****************************************************************************/ void _exit(int status) { (void) status; while (1) { } /* Hang here forever... */ } /**************************************************************************//** * @brief * Status of an open file. * * @param[in] file * Check status for this file. * * @param[in] st * Status information. * * @return * Returns 0 when st_mode is set to character special. *****************************************************************************/ int _fstat(int file, struct stat *st) { (void) file; st->st_mode = S_IFCHR; return 0; } /**************************************************************************//** * @brief Get process ID. *****************************************************************************/ int _getpid(void) { return 1; } /**************************************************************************//** * @brief * Query whether output stream is a terminal. * * @param[in] file * Descriptor for the file. * * @return * Returns 1 when query is done. *****************************************************************************/ int _isatty(int file) { (void) file; return 1; } /**************************************************************************//** * @brief Send signal to process. * @param[in] pid Process id (not used). * @param[in] sig Signal to send (not used). *****************************************************************************/ int _kill(int pid, int sig) { (void)pid; (void)sig; return -1; } /**************************************************************************//** * @brief * Set position in a file. * * @param[in] file * Descriptor for the file. * * @param[in] ptr * Poiter to the argument offset. * * @param[in] dir * Directory whence. * * @return * Returns 0 when position is set. *****************************************************************************/ int _lseek(int file, int ptr, int dir) { (void) file; (void) ptr; (void) dir; return 0; } /**************************************************************************//** * @brief * Read from a file. * * @param[in] file * Descriptor for the file you want to read from. * * @param[in] ptr * Pointer to the chacaters that are beeing read. * * @param[in] len * Number of characters to be read. * * @return * Number of characters that have been read. *****************************************************************************/ int _read(int file, char *ptr, int len) { int c, rxCount = 0; (void) file; while (len--) { if ((c = RETARGET_ReadChar()) != -1) { *ptr++ = c; rxCount++; } else { break; } } if (rxCount <= 0) { return -1; /* Error exit */ } return rxCount; } /**************************************************************************//** * @brief * Increase heap. * * @param[in] incr * Number of bytes you want increment the program's data space. * * @return * Rsturns a pointer to the start of the new area. *****************************************************************************/ caddr_t _sbrk(int incr) { static char *heap_end; char *prev_heap_end; if (heap_end == 0) { heap_end = &_end; } prev_heap_end = heap_end; heap_end += incr; return (caddr_t) prev_heap_end; } /**************************************************************************//** * @brief * Write to a file. * * @param[in] file * Descriptor for the file you want to write to. * * @param[in] ptr * Pointer to the text you want to write * * @param[in] len * Number of characters to be written. * * @return * Number of characters that have been written. *****************************************************************************/ int _write(int file, const char *ptr, int len) { int txCount; (void) file; for (txCount = 0; txCount < len; txCount++) { RETARGET_WriteChar(*ptr++); } return len; } #endif /* !defined( __CROSSWORKS_ARM ) && defined( __GNUC__ ) */ #if defined(__ICCARM__) /******************* * * Copyright 1998-2003 IAR Systems. All rights reserved. * * $Revision: 38614 $ * * This is a template implementation of the "__write" function used by * the standard library. Replace it with a system-specific * implementation. * * The "__write" function should output "size" number of bytes from * "buffer" in some application-specific way. It should return the * number of characters written, or _LLIO_ERROR on failure. * * If "buffer" is zero then __write should perform flushing of * internal buffers, if any. In this case "handle" can be -1 to * indicate that all handles should be flushed. * * The template implementation below assumes that the application * provides the function "MyLowLevelPutchar". It should return the * character written, or -1 on failure. * ********************/ #include #include #include "em_common.h" _STD_BEGIN /**************************************************************************//** * @brief Transmit buffer to USART1 * @param buffer Array of characters to send * @param nbytes Number of bytes to transmit * @return Number of bytes sent *****************************************************************************/ static int TxBuf(uint8_t *buffer, int nbytes) { int i; for (i = 0; i < nbytes; i++) { RETARGET_WriteChar(*buffer++); } return nbytes; } /* * If the __write implementation uses internal buffering, uncomment * the following line to ensure that we are called with "buffer" as 0 * (i.e. flush) when the application terminates. */ size_t __write(int handle, const unsigned char * buffer, size_t size) { /* Remove the #if #endif pair to enable the implementation */ size_t nChars = 0; if (buffer == 0) { /* * This means that we should flush internal buffers. Since we * don't we just return. (Remember, "handle" == -1 means that all * handles should be flushed.) */ return 0; } /* This template only writes to "standard out" and "standard err", * for all other file handles it returns failure. */ if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) { return _LLIO_ERROR; } /* Hook into USART1 transmit function here */ if (TxBuf((uint8_t *) buffer, size) != size) { return _LLIO_ERROR; } else { nChars = size; } return nChars; } size_t __read(int handle, unsigned char * buffer, size_t size) { /* Remove the #if #endif pair to enable the implementation */ int nChars = 0; /* This template only reads from "standard in", for all other file * handles it returns failure. */ if (handle != _LLIO_STDIN) { return _LLIO_ERROR; } for (/* Empty */; size > 0; --size) { int c = RETARGET_ReadChar(); if (c < 0) { break; } *buffer++ = c; ++nChars; } return nChars; } _STD_END #endif /* defined( __ICCARM__ ) */ #if defined(__CROSSWORKS_ARM) /* Pass each of these function straight to the USART */ int __putchar(int ch) { return(RETARGET_WriteChar(ch)); } int __getchar(void) { return(RETARGET_ReadChar()); } #endif /* defined( __CROSSWORKS_ARM ) */ #if defined(__CC_ARM) /******************************************************************************/ /* RETARGET.C: 'Retarget' layer for target-dependent low level functions */ /******************************************************************************/ /* This file is part of the uVision/ARM development tools. */ /* Copyright (c) 2005-2006 Keil Software. All rights reserved. */ /* This software may only be used under the terms of a valid, current, */ /* end user licence from KEIL for a compatible version of KEIL software */ /* development tools. Nothing else gives you the right to use this software. */ /******************************************************************************/ #include /* #pragma import(__use_no_semihosting_swi) */ struct __FILE{ int handle; }; /**Standard output stream*/ FILE __stdout; /**************************************************************************//** * @brief * Writes character to file * * @param[in] f * File * * @param[in] ch * Character * * @return * Written character *****************************************************************************/ int fputc(int ch, FILE *f) { return(RETARGET_WriteChar(ch)); } /**************************************************************************//** * @brief * Reads character from file * * @param[in] f * File * * @return * Character *****************************************************************************/ int fgetc(FILE *f) { return(RETARGET_ReadChar()); } /**************************************************************************//** * @brief * Tests the error indicator for the stream pointed * to by file * * @param[in] f * File * * @return * Returns non-zero if it is set *****************************************************************************/ int ferror(FILE *f) { /* Your implementation of ferror */ return EOF; } /**************************************************************************//** * @brief * Writes a character to the console * * @param[in] ch * Character *****************************************************************************/ void _ttywrch(int ch) { RETARGET_WriteChar(ch); } /**************************************************************************//** * @brief * Library exit function. This function is called if stack * overflow occurs. * * @param[in] return_code * Return code *****************************************************************************/ void _sys_exit(int return_code) { label: goto label;/* endless loop */ } #endif /* defined( __CC_ARM ) */ /** @} (end group RetargetIo) */