首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过UART读取firmware.bin文件?

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

Stack Overflow用户
提问于 2019-11-11 10:35:39
回答 2查看 858关注 0票数 1

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

如何读取大小为50,000字节的firmware.bin文件?我用手臂皮层控制器来编程。

我能够读取小于150个字节的.txt文件,但是当文件大小超过150个字节时,它的读取垃圾值。我的任务是读取5万字节文件,这是二进制文件.bin。

代码语言:javascript
复制
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 */
    }
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-11 20:52:43

要缓冲将在其他上下文中异步读取的数据(在ISR和“普通”线程之间),如本例所述,您应该使用FIFO或环形缓冲区,以便ISR能够在普通线程读取和处理数据时继续写入缓冲区。例如,考虑到:

代码语言:javascript
复制
#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, 0, {0} } ;

然后,ISR会将数据放在缓冲区中,这样:

代码语言:javascript
复制
ringBufPut( &UART1RxBuffer, LPC_UART1->RBR ) ;

这样,主线程就可以读取数据:

代码语言:javascript
复制
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 (反转put/get) --您的ISR目前只处理Rx。充分缓冲的I/O将导致更确定的时间。

票数 0
EN

Stack Overflow用户

发布于 2019-11-25 11:01:13

谢谢你的回应clifford。我所需要做的事几乎更接近了。我试着使用环形缓冲器,它起作用了,而且我几乎完成了这个工作。

但是,当我尝试读取大文件(48 of ) 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

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

代码语言:javascript
复制
#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:

代码语言:javascript
复制
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();
    }
}

用于接收数据:

代码语言:javascript
复制
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;
        }
    }
}

用于传送数据:

代码语言:javascript
复制
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], 1, 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, UART_INTCFG_THRE, DISABLE);
        // Reset Tx Interrupt state
        TxIntStat = RESET;
    }
    else{
        // Set Tx Interrupt state
        TxIntStat = SET;
        UART_IntConfig((LPC_UART_TypeDef *)LPC_UART0, UART_INTCFG_THRE, ENABLE);
    }
}
void UART_IntErr(uint8_t bLSErrType)
{
    uint8_t test;
    // Loop forever
    while (1){
        // For testing purpose
        test = bLSErrType;
    }
}

UART在中断中使用的接收和传输功能:

代码语言:javascript
复制
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功能:

代码语言:javascript
复制
uint32_t UARTSend(LPC_UART_TypeDef *UARTPort, uint8_t *txbuf, uint8_t buflen)
{
    uint8_t *data = (uint8_t *) txbuf;
    uint32_t bytes = 0;

    UART_IntConfig(UARTPort, UART_INTCFG_THRE, 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, UART_INTCFG_THRE, ENABLE);
    }

    return bytes;
}

uint32_t UARTReceive(LPC_UART_TypeDef *UARTPort, uint8_t *rxbuf, 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, UART_INTCFG_RBR, ENABLE);
    return bytes;
}

主要功能

代码语言:javascript
复制
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文件时出现问题。

请告诉我哪里出了问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58799725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档