一、软件FIFO解析
软件FIFO的实现通常依赖于编程语言提供的数据结构和算法。
用C语言实现的代码如下
void fifo8_init(struct FIFO8 *fifo, int size, unsigned char *buf)
/* FIFOバッファの初期化 */
{
fifo->size = size;
fifo->buf = buf;
fifo->free = size; /* 空き */
fifo->flags = 0;
fifo->p = 0; /* 書き込み位置 */
fifo->q = 0; /* 読み込み位置 */
return;
}
int fifo8_put(struct FIFO8 *fifo, unsigned char data)
/* FIFOへデータを送り込んで蓄える */
{
if (fifo->free == 0) {
/* 空きがなくてあふれた */
fifo->flags |= FLAGS_OVERRUN;
return -1;
}
fifo->buf[fifo->p] = data;
fifo->p++;
if (fifo->p == fifo->size) {
fifo->p = 0;
}
fifo->free--;
return 0;
}
int fifo8_get(struct FIFO8 *fifo)
/* FIFOからデータを一つとってくる */
{
int data;
if (fifo->free == fifo->size) {
/* バッファが空っぽのときは、とりあえず-1が返される */
return -1;
}
data = fifo->buf[fifo->q];
fifo->q++;
if (fifo->q == fifo->size) {
fifo->q = 0;
}
fifo->free++;
return data;
}
int fifo8_status(struct FIFO8 *fifo)
/* どのくらいデータが溜まっているかを報告する */
{
return fifo->size - fifo->free;
}
如上代码,FIFO是一个缓冲区,它可以管理数据的读取和写入,并返回FIFO当前状态。
可以说,在实时操作系统中,这种结构是极为重要的,试想一下,对于一直有数据的读取和写入的系统,为了防止数据的丢失,一昧的把缓存区做的更大是无济于事的,因为数据一直在被写入和读取,随着时间的推移仍然会发生溢出,并且数据的管理变得复杂。
使用FIFO之后,完美的解决了这些问题,FIFO广泛的应用在各种通信过程。
二、中断执行过程
1、调用set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32)设置IDT
2、当中断被触发后,CPU会自动跳转到_asm_inthandler21的位置执行操作
_asm_inthandler21:
PUSH ES
PUSH DS
PUSHAD
MOV EAX,ESP
PUSH EAX
MOV AX,SS
MOV DS,AX
MOV ES,AX
CALL _inthandler21
POP EAX
POPAD
POP DS
POP ES
IRETD
如上代码,PUSH将数据压入栈顶、POP将数据从栈顶取出。将DS和ES调整到与SS相等,再调用inthander21,返回以后,将所有寄存器再返回到原来的值,然后执行IRETD。
总结的说,就是CPU会先保存寄存器值,然后跳到中断服务函数执行中断。执行完毕后,再跳回中断发生前的位置。