MCU:MSPM0G3507
前段時間在課內(nèi)做實驗的時候碰到了比較豐富的交互需求,遂打開UART,#include "stdio.h",然后開始重定向。雖然網(wǎng)上有廣為流傳的重定向方案,但是常年玩STM32的我有點迷惑:為什么TI Driverlib的重定向需要定義三個函數(shù)呢?
Trial
按照 STM32 重定向的方法,先對fputc進行重定向:
int fputc(int _c, FILE *_fp) {
while((UART0 - > STAT & UART_STAT_TXFF_MASK));
UART0 - > TXDATA = _c;
return _c;
}
觀察到,在這種重定向的方案下,printf函數(shù)可以輸出常字符串,但是無法進行變量的格式化輸出。
根據(jù)網(wǎng)絡(luò)上的方案,補充fputs和puts函數(shù),稍作修改:
int fputs(const char *restrict s, FILE *restrict stream) {
uint16_t i, len;
len = strlen(s);
for (i = 0; i < len; i++) {
fputc(s[i], stream);
}
return len;
}
int puts(const char *s) {
int count = fputs(s, stdout);
count += fputs("n", stdout);
return count;
}
在這種重定向方法下,printf成功實現(xiàn)了完整的重定向,可以進行變量的格式化輸出——但是,sprintf依然無法工作,為什么呢?
觀察三個函數(shù)的輸入?yún)?shù),其中兩個都包含了一個FILE*輸入變量,但是我們在使用的時候卻完全沒用到。找到FILE的定義:
struct __sFILE {
int fd; /* File descriptor */
unsigned char* buf; /* Pointer to start of buffer */
unsigned char* pos; /* Position in buffer */
unsigned char* bufend; /* Pointer to end of buffer */
unsigned char* buff_stop; /* Pointer to last read char in buffer */
unsigned int flags; /* File status flags (see below) */
};
typedef struct __sFILE FILE;
可見,在TI的庫中, FILE類型并沒有被簡單地改為簡單的存儲指針,而是依然保留了“數(shù)據(jù)流”的形式 。再結(jié)合debug中端點的觸發(fā)情況,以及函數(shù)之間的調(diào)用關(guān)系,嘗試對FILE*指針進行寫入。若調(diào)用了puts,認為上層的標準輸出走的是printf(),就向下傳遞空指針,將輸出導(dǎo)向 UART。如果stream不是自己設(shè)定的空指針,就去編輯stream指向的緩沖區(qū)。
Result
對重定向的三個函數(shù)進行如下修改:
int fputc(int _c, FILE *_fp) {
if(!(_fp)) {
while((UART0 - > STAT & UART_STAT_TXFF_MASK));
UART0 - > TXDATA = _c;
}
else
*(_fp- >pos) = _c;
return _c;
}
int fputs(const char* restrict s, FILE* restrict stream) {
uint16_t i, len;
len = strlen(s);
for(unsigned int i=0; i < len; i++) {
fputc(s[i], stream);
if(stream) stream- >pos++;
}
return len;
}
int puts(const char *_ptr) {
int count = fputs(_ptr,NULL);
count += fputs("n",NULL);
return count;
}
重定向成功,sprintf和printf均可以正常工作!
More…
那個結(jié)構(gòu)體我還沒用完,估計在重定向輸入流的時候會用到更多的元素。但是知道這些已經(jīng)足夠了,可以搞點花招,比如把UARTx → TXDATA直接丟到stream里面去,當然FIFO只有一個入口,不需要地址偏移,這么看也是有點麻煩;或者直接把自己的指定buffer設(shè)為默認輸出區(qū)域,等等,雖然更復(fù)雜了,但是相對于僅僅把FILE作為一個獨立指針,還是更加靈活有趣的!
實力尚淺,還請多多指教!
審核編輯 黃宇
-
uart
+關(guān)注
關(guān)注
22文章
1322瀏覽量
107027 -
DriverLib
+關(guān)注
關(guān)注
0文章
3瀏覽量
2083
發(fā)布評論請先 登錄
TI 攜手 NVIDIA 推出面向下一代 AI 數(shù)據(jù)中心的完整 800 VDC 電源架構(gòu)
【乾芯QXS320F開發(fā)板試用】基于printf重定向的高速串口調(diào)試方案
Linux中13個基本Cat命令示例
【瑞薩RA6E2地奇星開發(fā)板試用】串口通信報錯:標準輸出流 stdout 未定義
跌落試驗的核心:解析自由跌落、定向跌落等主要測試模式的區(qū)別
廣凌標準化考場建設(shè)方案的核心模塊
UART在5.2.0版本E2S中的重定向
【RA4E2開發(fā)板評測】FSP5.2之后的串口重定向問題解決方法
LWH12060YAH國產(chǎn)電源模塊完美替代TI PTH12060YAH方案
MEMS定向短節(jié)可以為水平定向鉆機提供哪些數(shù)據(jù)?
【RA-Eco-RA6M4開發(fā)板評測】移植xprintf實現(xiàn)標準輸入輸出
20205新疆國際煤博會:礦用尋北儀提供高可靠定向解決方案
MEMS定向短節(jié)在HDD中如何精準定向?
MEMS陀螺工具定向短節(jié)全面升級,重新定義測量標準
為什么MEMS定向短節(jié)能引領(lǐng)鉆探未來
TI Driverlib 標準輸出完整重定向的改進方案
評論