如何通过UART读取firmware.bin文件?

我必须通过UART读取firmware.bin文件,文件大小为50,000字节。我编写了代码,但在读取文件时显示了垃圾值。

我如何读取50,000字节大小的firmware.bin文件?我使用ARM cortex控制器进行编程。

我能够读取大小小于150字节的.txt文件,但是当文件大小大于150字节时,其读取垃圾值。我的任务是读取50,000字节的二进制文件.bin

void read file()
{
UART1_TxString("AT+QFOPEN=\"RAM:FIRMWARE.BIN\",2\r");
                                              //2:only read for opend file.
WaitForExpectedResponse("+QFOPEN:",1000);    // timeout 1000ms       
                                     //in response +QFOPEN: 134072 filehandler
UART1_TxString("AT+QFREAD=134072\r");
connect = WaitForConnectResponse("CONNECT",60000); // timeout 60000ms
                       // in response CONNECT 50000 (i.e.filesize 50,000 byte)
while(connect)
{    
   int i=0,j=0;
   char* param = strchr(UART1Buffer,'T') + (strlen(size_buff)+2);
          // UART1Buffer its UART-Buffer of size 160.
          // size_buff store file size to be read in string (50000)
          // size_int  store file size to be read in integer(50000)
 for(i=0;i<size_int;i++){           
        UART2_Printf(" %c ",*param);// print UART-BUFFER-DATA
  }
 }
}
void UART1_IRQHandler ( void ) 
{
  uint8_t IIRValue,LSRValue;
  uint8_t Dummy = Dummy;

  IIRValue = LPC_UART1->IIR;

  IIRValue >>= 1;           /* skip pending bit in IIR */
  IIRValue &= 0x07;         /* check bit 1~3,interrupt identification */
  if ( IIRValue == IIR_RLS )        /* Receive Line Status */
  {
    LSRValue = LPC_UART1->LSR;

    if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
    {
      UART1Status = LSRValue;
      Dummy = LPC_UART1->RBR;       /* Dummy read on RX to clear 
                                interrupt,then bail out */
      return;
    }
    if ( LSRValue & LSR_RDR )   /* Receive Data Ready */            
    {
      UART1Buffer[UART1Count] = LPC_UART1->RBR;
      UART1Count++;
      if ( UART1Count == BUFSIZE )  // BUFSIZE= 160
      {
        UART1Count = 0;     /* buffer overflow */
      } 
    }
  }
  else if ( IIRValue == IIR_RDA )   /* Receive Data Available */
  {
    UART1Buffer[UART1Count] = LPC_UART1->RBR;
    UART1Count++;
    if ( UART1Count == BUFSIZE )
    {
      UART1Count = 0;       /* buffer overflow */
    }
  }
}
flossyeye2 回答:如何通过UART读取firmware.bin文件?

要缓冲将在其他上下文中(在这种情况下,在ISR和“普通”线程之间)异步读取的数据,应使用FIFO或环形缓冲区,以便ISR可以继续写入缓冲区而普通线程正在读取和处理它。例如,给定:

#include <stdint.h>
#include <stdatomic.h>

#define BUFFLEN ((uint8_t)128u)               // Must be a power of 2
#define BUFFMODMASK ((uint8_t)(BUFFLEN - 1))  // modulo BUFFLEN mask

typedef volatile struct
{
    uint8_t write_idx ;
    uint8_t read_idx ;
    atomic_int count ;
    uint8_t data[BUFFLEN] ;
} tRingBuf ;

void ringBufPut( tRingBuf* buffer,uint8_t ch )
{
    if( buffer->count < BUFFLEN )
    {
        buffer->data[buffer->write_idx++] = ch ;
        buffer->write_idx &= BUFFMODMASK ;
        buffer->count++ ;
    }
}

int ringBufGet( tRingBuf* buffer )
{
    int ch = -1 ;
    if( buffer->count > 0 )
    {
        ch =  (int)buffer->data[buffer->read_idx++] ;    
        buffer->read_idx &= BUFFMODMASK ;
        buffer->count-- ;
    }

    return ch ;
}

tRingBuf UART1RxBuffer = { 0,{0} } ;

然后,您的ISR将数据放入缓冲区中:

ringBufPut( &UART1RxBuffer,LPC_UART1->RBR ) ;

然后您的主线程可以读取数据,从而:

for( int i = 0; i < size_int; i++ )
{           
    int ch = ringBufGet( &UART1RxBuffer ) ;
    if( ch > 0 )
    {
        uint8_t byte = (uint8_t)ch ;

        // ... do something with the data here
        // For example...
        UART2_Printf( "%02X",(unsigned)byte ) ;
    }
}

对于所有UART,以相同的方式(反转放置/获取)实现UART Tx可能会做得很好-您的ISR当前仅处理Rx。完全缓冲的I / O将带来更多确定性的时序。

,

感谢您的回应。几乎非常接近我需要做的事情。 我尝试使用环形缓冲区来工作,并且几乎做到了。

但是,当我尝试读取大文件(48kB) Update.BIN 文件时, 它正在读取完整的文件,但是当我将此读取的文件与实际文件进行比较时,会发现数据丢失和数据不匹配 (正在附加实际文件以及我随即阅读的内容)。

我通过UART环形缓冲区读取的文件: https://www.dropbox.com/s/93k3i3r598jkxro/My_Read_file.log?dl=0

我尝试读取的实际文件:https://www.dropbox.com/s/bmh5wyurrdvvtqx/Update.BIN.txt?dl=0

我的环形缓冲区代码如下:

#define UART_RING_BUFSIZE 256
#define __BUF_MASK (UART_RING_BUFSIZE-1)
#define __BUF_IS_FULL(head,tail) ((tail&__BUF_MASK)==((head+1)&__BUF_MASK))
#define __BUF_WILL_FULL(head,tail) ((tail&__BUF_MASK)==((head+2)&__BUF_MASK))
#define __BUF_IS_EMPTY(head,tail) ((head&__BUF_MASK)==(tail&__BUF_MASK))
#define __BUF_RESET(bufidx) (bufidx=0)
#define __BUF_INCR(bufidx)  (bufidx=(bufidx+1)&__BUF_MASK)

typedef struct
{
    __IO uint32_t tx_head;                /*!< UART Tx ring buffer head index */
    __IO uint32_t tx_tail;                /*!< UART Tx ring buffer tail index */
    __IO uint32_t rx_head;                /*!< UART Rx ring buffer head index */
    __IO uint32_t rx_tail;                /*!< UART Rx ring buffer tail index */
    __IO uint8_t  tx[UART_RING_BUFSIZE];  /*!< UART Tx data ring buffer */
    __IO uint8_t  rx[UART_RING_BUFSIZE];  /*!< UART Rx data ring buffer */
} UART_RING_BUFFER_T;


// UART Ring buffer
UART_RING_BUFFER_T rb;

// Current Tx Interrupt enable state
__IO FlagStatus TxIntStat;

中断IRQHandler:

void UART0_IRQHandler(void)
{
    uint32_t intsrc,tmp,tmp1;

    /* Determine the interrupt source */
    intsrc = UART_GetIntId(LPC_UART0);
    tmp = intsrc & UART_IIR_INTID_MASK;

    // Receive Line Status
    if (tmp == UART_IIR_INTID_RLS){
        // Check line status
        tmp1 = UART_GetLineStatus(LPC_UART0);
        // Mask out the Receive Ready and Transmit Holding empty status
        tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \
                | UART_LSR_BI | UART_LSR_RXFE);
        // If any error exist
        if (tmp1) {
                UART_IntErr(tmp1);
        }
    }
    // Receive Data Available or Character time-out
    if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)){
            UART_IntReceive();
    }
    // Transmit Holding Empty
    if (tmp == UART_IIR_INTID_THRE){
            UART_IntTransmit();
    }
}

用于接收数据:

void UART_IntReceive(void)
{
    uint8_t temp;
    uint32_t recv_byte;

    while(1){

        recv_byte = UART_Receive((LPC_UART_TypeDef *)LPC_UART0,&temp,1,NONE_BLOCKING);
        // If data received
        if (recv_byte){

            if (!__BUF_IS_FULL(rb.rx_head,rb.rx_tail)){
                rb.rx[rb.rx_head] = temp;
                __BUF_INCR(rb.rx_head);
            }
        }
        // no more data
        else {
            break;
        }
    }
}

用于传输数据:

void UART_IntTransmit(void)
{
    // Disable THRE interrupt
    UART_IntConfig((LPC_UART_TypeDef *)LPC_UART0,UART_INTCFG_THRE,DISABLE);

    while (UART_CheckBusy((LPC_UART_TypeDef *)LPC_UART0) == SET);

    while (!__BUF_IS_EMPTY(rb.tx_head,rb.tx_tail))
    {
        /* Move a piece of data into the transmit FIFO */
        if (UART_Send((LPC_UART_TypeDef *)LPC_UART0,(uint8_t *)&rb.tx[rb.tx_tail],NONE_BLOCKING)){
        /* Update transmit ring FIFO tail pointer */
        __BUF_INCR(rb.tx_tail);
        } else {
            break;
        }
    }

    if (__BUF_IS_EMPTY(rb.tx_head,rb.tx_tail)) {
        UART_IntConfig((LPC_UART_TypeDef *)LPC_UART0,DISABLE);
        // Reset Tx Interrupt state
        TxIntStat = RESET;
    }
    else{
        // Set Tx Interrupt state
        TxIntStat = SET;
        UART_IntConfig((LPC_UART_TypeDef *)LPC_UART0,ENABLE);
    }
}
void UART_IntErr(uint8_t bLSErrType)
{
    uint8_t test;
    // Loop forever
    while (1){
        // For testing purpose
        test = bLSErrType;
    }
}

UART接收和发送功能在中断中使用:

uint32_t UART_Send(LPC_UART_TypeDef *UARTx,uint8_t *txbuf,uint32_t buflen,TRANSFER_BLOCK_Type flag)
{
    uint32_t bToSend,bSent,timeOut,fifo_cnt;
    uint8_t *pChar = txbuf;

    bToSend = buflen;

    // blocking mode
    if (flag == BLOCKING) {
        bSent = 0;
        while (bToSend){
            timeOut = UART_BLOCKING_TIMEOUT;
            // Wait for THR empty with timeout
            while (!(UARTx->LSR & UART_LSR_THRE)) {
                if (timeOut == 0) break;
                timeOut--;
            }
            // Time out!
            if(timeOut == 0) break;
            fifo_cnt = UART_TX_FIFO_SIZE;
            while (fifo_cnt && bToSend){
                UART_SendByte(UARTx,(*pChar++));
                fifo_cnt--;
                bToSend--;
                bSent++;
            }
        }
    }
    // None blocking mode
    else {
        bSent = 0;
        while (bToSend) {
            if (!(UARTx->LSR & UART_LSR_THRE)){
                break;
            }
            fifo_cnt = UART_TX_FIFO_SIZE;
            while (fifo_cnt && bToSend) {
                UART_SendByte(UARTx,(*pChar++));
                bToSend--;
                fifo_cnt--;
                bSent++;
            }
        }
    }
    return bSent;
}
uint32_t UART_Receive(LPC_UART_TypeDef *UARTx,uint8_t *rxbuf,\
        uint32_t buflen,TRANSFER_BLOCK_Type flag)
{
    uint32_t bToRecv,bRecv,timeOut;
    uint8_t *pChar = rxbuf;

    bToRecv = buflen;

    // Blocking mode
    if (flag == BLOCKING) {
        bRecv = 0;
        while (bToRecv){
            timeOut = UART_BLOCKING_TIMEOUT;
            while (!(UARTx->LSR & UART_LSR_RDR)){
                if (timeOut == 0) break;
                timeOut--;
            }
            // Time out!
            if(timeOut == 0) break;
            // Get data from the buffer
            (*pChar++) = UART_ReceiveByte(UARTx);
            bToRecv--;
            bRecv++;
        }
    }
    // None blocking mode
    else {
        bRecv = 0;
        while (bToRecv) {
            if (!(UARTx->LSR & UART_LSR_RDR)) {
                break;
            } else {
                (*pChar++) = UART_ReceiveByte(UARTx);
                bRecv++;
                bToRecv--;
            }
        }
    }
    return bRecv;
}

UART TX和RX功能:

uint32_t UARTSend(LPC_UART_TypeDef *UARTPort,uint8_t buflen)
{
    uint8_t *data = (uint8_t *) txbuf;
    uint32_t bytes = 0;

    UART_IntConfig(UARTPort,DISABLE);

    while ((buflen > 0) && (!__BUF_IS_FULL(rb.tx_head,rb.tx_tail)))
    {
        /* Write data from buffer into ring buffer */
        rb.tx[rb.tx_head] = *data;
        data++;

        /* Increment head pointer */
        __BUF_INCR(rb.tx_head);

        bytes++;
        buflen--;
    }

    if (TxIntStat == RESET) {
        UART_IntTransmit();
    }
    else {
        UART_IntConfig(UARTPort,ENABLE);
    }

    return bytes;
}

uint32_t UARTReceive(LPC_UART_TypeDef *UARTPort,uint8_t buflen)
{
    uint8_t *data = (uint8_t *) rxbuf;
    uint32_t bytes = 0;

    UART_IntConfig(UARTPort,UART_INTCFG_RBR,DISABLE);


    while ((buflen > 0) && (!(__BUF_IS_EMPTY(rb.rx_head,rb.rx_tail))))
    {
        /* Read data from ring buffer into user buffer */
        *data = rb.rx[rb.rx_tail];
        data++;

        /* Update tail pointer */
        __BUF_INCR(rb.rx_tail);

        /* Increment data count and decrement buffer size count */
        bytes++;
        buflen--;
    }
    UART_IntConfig(UARTPort,ENABLE);
    return bytes;
}

主要功能

void main(){

uint32_t idx=0,len[enter link description here][1]=0;
    __IO FlagStatus exitflag;
    uint8_t buffer[100]

// reset exit flag
    exitflag = RESET;
while (exitflag == RESET)
    {
        len = 0;
        while (len == 0)
        {
            len = UARTReceive((LPC_UART_TypeDef *)LPC_UART0,buffer,sizeof(buffer));
        }
        idx = 0;
        while (idx < len)
        {
          UARTSend((LPC_UART_TypeDef *)LPC_UART0,&buffer[idx],1);
          idx++;
        }
    }
}

此外,观察到读取.txt文件时不会在读取时遗漏任何字节。只是在读取.bin文件时出现的问题。

请让我知道哪里出了问题。

本文链接:https://www.f2er.com/3124921.html

大家都在问