mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #770 from GustavWi/iar_mbed
Fix IAR serial fgets fgetc Taken from PR #770: setbuf(_file, NULL), and std::setvbuf(_file,NULL,_IONBF,NULL) should both give an unbuffered stream (the data is directly written to the input buffer). IAR sets a buffer anyway of size 512 bytes for these calls. Calling setvbuff(_file,buf,_IONBF,NULL) with a buffer that is not a NULL pointer sets the buffer to size one. Which means that as soon as a char is read it is written to the real buffer. If people are interested in looking at this further they can look at the files under ARM/src/dlib: fgets.c, fflush.c, xfrpep.c and xfwprep.cpull/776/head
commit
ea49132428
|
|
@ -21,6 +21,10 @@
|
||||||
|
|
||||||
namespace mbed {
|
namespace mbed {
|
||||||
|
|
||||||
|
extern void mbed_set_unbuffered_stream(FILE *_file);
|
||||||
|
extern int mbed_getc(FILE *_file);
|
||||||
|
extern char* mbed_gets(char *s, int size, FILE *_file);
|
||||||
|
|
||||||
class Stream : public FileLike {
|
class Stream : public FileLike {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ Stream::Stream(const char *name) : FileLike(name), _file(NULL) {
|
||||||
char buf[12]; /* :0x12345678 + null byte */
|
char buf[12]; /* :0x12345678 + null byte */
|
||||||
std::sprintf(buf, ":%p", this);
|
std::sprintf(buf, ":%p", this);
|
||||||
_file = std::fopen(buf, "w+");
|
_file = std::fopen(buf, "w+");
|
||||||
setbuf(_file, NULL);
|
mbed_set_unbuffered_stream(_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream::~Stream() {
|
Stream::~Stream() {
|
||||||
|
|
@ -41,11 +41,11 @@ int Stream::puts(const char *s) {
|
||||||
}
|
}
|
||||||
int Stream::getc() {
|
int Stream::getc() {
|
||||||
fflush(_file);
|
fflush(_file);
|
||||||
return std::fgetc(_file);
|
return mbed_getc(_file);
|
||||||
}
|
}
|
||||||
char* Stream::gets(char *s, int size) {
|
char* Stream::gets(char *s, int size) {
|
||||||
fflush(_file);
|
fflush(_file);
|
||||||
return std::fgets(s,size,_file);
|
return mbed_gets(s,size,_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Stream::close() {
|
int Stream::close() {
|
||||||
|
|
|
||||||
|
|
@ -480,3 +480,55 @@ extern "C" caddr_t _sbrk(int incr) {
|
||||||
return (caddr_t) prev_heap;
|
return (caddr_t) prev_heap;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace mbed {
|
||||||
|
|
||||||
|
void mbed_set_unbuffered_stream(FILE *_file) {
|
||||||
|
#if defined (__ICCARM__)
|
||||||
|
char buf[2];
|
||||||
|
std::setvbuf(_file,buf,_IONBF,NULL);
|
||||||
|
#else
|
||||||
|
setbuf(_file, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbed_getc(FILE *_file){
|
||||||
|
#if defined (__ICCARM__)
|
||||||
|
/*This is only valid for unbuffered streams*/
|
||||||
|
int res = std::fgetc(_file);
|
||||||
|
if (res>=0){
|
||||||
|
_file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
|
||||||
|
_file->_Rend = _file->_Wend;
|
||||||
|
_file->_Next = _file->_Wend;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
#else
|
||||||
|
return std::fgetc(_file);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
char* mbed_gets(char*s, int size, FILE *_file){
|
||||||
|
#if defined (__ICCARM__)
|
||||||
|
/*This is only valid for unbuffered streams*/
|
||||||
|
char *str = fgets(s,size,_file);
|
||||||
|
if (str!=NULL){
|
||||||
|
_file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
|
||||||
|
_file->_Rend = _file->_Wend;
|
||||||
|
_file->_Next = _file->_Wend;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
#else
|
||||||
|
return std::fgets(s,size,_file);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mbed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue