我必须通过UART读取firmware.bin文件,文件大小为50,000字节.i编写代码,但它在读取文件时显示垃圾值。
如何读取大小为50,000字节的firmware.bin文件?我用手臂皮层控制器来编程。
我能够读取小于150个字节的.txt文件,但是当文件大小超过150个字节时,它的读取垃圾值。我的任务是读取5万字节文件,这是二进制文件.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 */
}
}
}发布于 2019-11-11 20:52:43
要缓冲将在其他上下文中异步读取的数据(在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,您可能会很好地实现UART Tx (反转put/get) --您的ISR目前只处理Rx。充分缓冲的I/O将导致更确定的时间。
发布于 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
我的循环缓冲区代码如下:
#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], 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在中断中使用的接收和传输功能:
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 *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;
}主要功能
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://stackoverflow.com/questions/58799725
复制相似问题