6

rs485 経由で 921.6Kbaud で 15 バイトのパケットを処理する小さなアプリケーション用の受信バッファのアイデアを探しています。UART ISR とメインの間のインターフェイスとして循環バッファを使用することを考えています。載せたかったマイクロプロセッサなので

while (uartindex!=localindex) { do stuff } 

の中に

while (;;) {do forever} 

メインの一部ですが、これは受け入れられないと言われています。

同様の状況下で、人々は UART をどのように扱うのでしょうか?

4

2 に答える 2

6

ISR は FIFO を埋める必要があります。メインはそれを消費する必要があります。

非常に単純な fifo アルゴリズムを以下に示します。

#define RINGFIFO_SIZE (1024)              /* serial buffer in bytes (power 2)   */
#define RINGFIFO_MASK (RINGFIFO_SIZE-1ul) /* buffer size mask                   */

/* Buffer read / write macros                                                 */
#define RINGFIFO_RESET(ringFifo)      {ringFifo.rdIdx = ringFifo.wrIdx = 0;}
#define RINGFIFO_WR(ringFifo, dataIn) {ringFifo.data[RINGFIFO_MASK & ringFifo.wrIdx++] = (dataIn);}
#define RINGFIFO_RD(ringFifo, dataOut){ringFifo.rdIdx++; dataOut = ringFifo.data[RINGFIFO_MASK & (ringFifo.rdIdx-1)];}
#define RINGFIFO_EMPTY(ringFifo)      (ringFifo.rdIdx == ringFifo.wrIdx)
#define RINGFIFO_FULL(ringFifo)       ((RINGFIFO_MASK & ringFifo.rdIdx) == (RINGFIFO_MASK & (ringFifo.wrIdx+1)))
#define RINGFIFO_COUNT(ringFifo)      (RINGFIFO_MASK & (ringFifo.wrIdx - ringFifo.rdIdx))

/* buffer type                                                                */
typedef struct{
    uint32_t size;
    uint32_t wrIdx;
    uint32_t rdIdx;
    uint8_t data[RINGFIFO_SIZE];
} RingFifo_t;
RingFifo_t gUartFifo;

(この FIFO アルゴリズムには注意が必要です。サイズは 2 の累乗でなければなりません)

ISR は次のように動作する必要があります。

void ISR_Handler()
{
    uint8_t c;
    while(UART_NotEmpty()) {
        c = UART_GetByte();
        RINGFIFO_WR(gUartFifo, c);
    }
}

そしてメイン:

while(1)
{
    if (!RINGFIFO_EMPTY(gUartFifo)) {
        /* consume fifo using RINGFIFO_RD */
    }    
}

このアルゴリズムは、FIFO をメイン ループから直接読み取ります。中間層を使用して、バッファにフル パケットがあるかどうかを確認し、main が次のようになるように処理する必要があります。

uint8_t ptrToPacket;
uint32_t packetSize;
while(1)
{
    if (!Uart_HasValidPacket()) {
        Uart_GetPacket(&ptrToPacket, &packetSize)
        /* Process packet using ptrToPacket and packetSize */
    }    
}
于 2013-03-11T19:35:01.193 に答える
3

あなたが提案するアプローチuartindexは、メインループに書き込まれず(割り込みが無効になっている間に初期化する場合を除く)、localindex割り込みルーチンによって決して触れられない場合、おそらく実行可能です。

バッファ サイズを 2 の累乗にし、2 つのインデックスに符号なし整数を使用し、32 ビット サイズ全体を自由にカウントできるようにすることをお勧めします。「stuff」ルーチンと「fetch」ルーチンの両方でバッファにインデックスを付ける場合は、ビット マスキングを使用します。そうすれば、

(unsigned)(uartindex-localindex) 

バッファがいっぱいになった場合でも、バッファがいっぱいの場合に特別なケースの動作を要求したり、N バイトのバッファを N-1 個のアイテムを保持するように制限したりせずに、バッファ内の文字数を示す必要があります。

前述の式の型キャストは厳密には必要ではありませんが、符号なしの数量を減算する際のラッピング動作が意図的予期されていることが明らかになるため、含めることをお勧めします。

于 2013-03-11T17:35:26.387 に答える