как прочитать файл firmware.bin через UART? - PullRequest
1 голос
/ 11 ноября 2019

Мне нужно прочитать файл firmware.bin через UART, размер файла 50 000 байт. Я пишу код, но он показывает значение мусора при чтении файла.

как я могу прочитать файл firmware.bin размером 50000 байт.? Я использую контроллер ARM Cortex для программирования.

я могу прочитать .txt файл размером менее 150 байт, но когда размер файла становится больше 150 байт, это значение для чтения мусора. и моя задача - прочитать файл размером 50000 байт, который является двоичным файлом .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 */
    }
  }
}

1 Ответ

0 голосов
/ 11 ноября 2019

Для буферизации данных, которые будут асинхронно считываться в каком-либо другом контексте (между 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, 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 Tx таким же образом (полностью изменяя пут / получи) для всех UART - ваш ISR в настоящее время имеет дело только с Rx. Полностью буферизованный I /O приведет к более детерминированному выбору времени.

...