typedef?struct?{? ??uint8_t?buffer[256]; ?// 存放數(shù)據(jù)(飯盒)? ??uint16_t?write_index; ?// 寫入指針(打飯窗口)? ??uint16_t?read_index; ??// 讀取指針(學(xué)生排隊(duì)領(lǐng)飯)? ??uint16_t?count; ? ? ? ?// 當(dāng)前存放了多少數(shù)據(jù)(隊(duì)伍長度)} FIFO_t;
buffer[256]就是 256 個飯盒,用來存數(shù)據(jù)。
write_index負(fù)責(zé)裝飯(存數(shù)據(jù))。
read_index負(fù)責(zé)拿飯(取數(shù)據(jù))。
count記錄當(dāng)前隊(duì)伍里有多少人(存了多少數(shù)據(jù))。
void?fifo_init(FIFO_t *fifo) {? ? fifo->write_index =?0;? ? fifo->read_index =?0;? ? fifo->count =?0;}
剛開始都清0
bool fifo_write(FIFO_t *fifo, uint8_t?data) {? ??if?(fifo->count ==?256)?return?false; ?// 飯盒滿了,不能再存數(shù)據(jù)? ? fifo->buffer[fifo->write_index] =?data; ?// 把數(shù)據(jù)存入 FIFO? ? fifo->write_index = (fifo->write_index +?1) %?256; ?// 環(huán)形隊(duì)列? ? fifo->count++;? ??return?true;}
這里唯一的難點(diǎn)就是環(huán)形的概念
write_index?=?5;write_index?= (write_index +?1) %?256; ?// 變成 6
write_index?=?254;write_index?= (write_index +?1) %?256; ?// 變成 255
write_index?=?255;write_index?= (write_index +?1) %?256; ?// 變成 0(回到起點(diǎn))
檢查 FIFO 是否滿了(飯盒是否裝滿了),滿了就不能再寫入。
寫入數(shù)據(jù)后,寫指針 write_index 往前移動,到下一個空位。隊(duì)伍人數(shù) count++,表示數(shù)據(jù)增加了。
bool fifo_read(FIFO_t *fifo, uint8_t *data) {? ??if?(fifo->count ==?0)?return?false; ?// 隊(duì)伍沒人,無法取數(shù)據(jù)? ? *data?= fifo->buffer[fifo->read_index]; ?// 取出 FIFO 里的數(shù)據(jù)? ? fifo->read_index = (fifo->read_index +?1) %?256; ?// 環(huán)形隊(duì)列? ? fifo->count--;? ??return?true;}
如果 FIFO 為空,說明沒人排隊(duì),無法取數(shù)據(jù)。
讀取 FIFO 里的數(shù)據(jù)(拿飯),讀指針 read_index 往前走。
隊(duì)伍人數(shù) count--,說明數(shù)據(jù)減少了。
int?main()?{? ? FIFO_t fifo;? ??fifo_init(&fifo);? ??// 寫入數(shù)據(jù)? ??fifo_write(&fifo,?10); ?? ??fifo_write(&fifo,?20); ?? ??fifo_write(&fifo,?30); ?? ??// 讀取數(shù)據(jù)? ??uint8_t?value;? ??while?(fifo_read(&fifo, &value)) {? ? ? ??printf("取出的數(shù)據(jù): %d\n", value);? ? }? ??return?0;}
FIFO 就像一個排隊(duì)取飯的過程,先進(jìn)的先出!