Search code examples
armembeddedembedded-resourceuartfirmware

how to read firmware.bin file through UART?


i have to read firmware.bin file through UART, File size 50,000 byte.i write code but its shows garbage value while reading the file.

how i can read firmware.bin file of size 50,000 byte.? i use ARM cortex controller for programming.

i able to read .txt file of size less than 150 byte but when file size goes higher than 150 byte its read garbage value. and my task is to read 50,000 byte file which is binary file .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 */
    }
  }
}

Solution

  • To buffer data that will be asynchronously read in some other context (between an ISR and a "normal" thread as in this case, you should use a FIFO or ring buffer in order that the ISR can continue to write to the buffer while the normal thread is reading and processing it. For example, given:

    #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} } ;
    

    Your ISR will then place data in the buffer thus:

    ringBufPut( &UART1RxBuffer, LPC_UART1->RBR ) ;
    

    Then your main thread can read the data thus:

    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 ) ;
        }
    }
    

    You would do well perhaps to implement the UART Tx in the same way (reversing the put/get) for all UARTs - your ISR only deals with Rx currently. Fully buffered I/O will lead to more deterministic timing.