ARM newlib使用中遇到的问题

NewlibANSIC库的一个实现,是一个更加精简和易于移植的版本,我在移植NewlibCM4上的时候遇到了一个比较奇怪的问题,串口上的getchar工作不正常。

Newlib的移植比较简单的就是实现一些syscalls函数就可以了,比较重要的是以下几个函数:

int _close(int file);
int _isatty(int file);
int _open(const char *name, int flags, int mode);

int _fstat(int file, struct stat *st);

int _write(int file, char *p, int len);
int _read(int file, char *p, int len);

static char *heap_end = (char *) __heap_start;

char *_sbrk(int incr);

int _kill(int pid, int sig);

上面很多函数一般都可以直接返回0或1或-1等等就可以了,和串口相关的函数是_write_read,不过移植完成运行的时候printf可以正常工作,但是运行getchar的时候系统会锁住,跟踪调试发现到_read函数的参数len1024,而不是我期望的1,我怎么可以串口一直按1024次呀,呜呜~~~

后来找了一大圈发现newlib里面stdin是一个文件,而这个文件是有一个1024长度的buffer的,所以没有读满这个buffer是不会返回的,也就会一直在循环中等待,直到1024个字符读满,这个丧心病狂的设计,当然在真正系统设计中还是很有效率的。找到问题的根源就好办了,解决方法就是直接将这个buffer设置为0就好啦,设置方法如下:

setvbuf(stdin, NULL, _IONBF, 0);

运行了上面的设置之后,系统运行正常,getcharputchar运行都正常。

其实适配newlib虽然有点小麻烦,不过后面可以不ASNC C兼容,还是有一定的好处的,也可以降低后期的开发成本。

发表新评论