写了一个串口接收的 FIFO ,一直都看不出有什么问题!

2019-12-23 18:38发布

bsp_US1_RX_int (u8 Data)       这一条是串口接收中断的时候调用,并把出带入。
bsp_US1_RX    (u8 * Data)      这一条是取出缓冲区的数据

现在问题是这样的,是不是的数据会丢一两个位,并且丢了之后,以后收到的数据都会出现错位!
正确的应该是  0123456789  ,但错位后收到的数据  5012345678。  



u16     bsp_US1_RX       (u8 * Data)
{   
    short temp=0;
    while(US1_RX_FIFO_user)
    {
        *Data++ = US1_RX_FIFO[US1_RX_FIFO_tail++];              
        if(US1_RX_FIFO_tail == US1_RX_FIFO_Siz)     
            US1_RX_FIFO_tail = 0;                  
        US1_RX_FIFO_user--;

        temp++;
    }
   
    return temp;
}
inline s8      bsp_US1_RX_int   (u8 Data)
{   
    if(US1_RX_FIFO_Siz - US1_RX_FIFO_user -1 )
    {
        US1_RX_FIFO[US1_RX_FIFO_head++] = Data;      
        if(US1_RX_FIFO_head == US1_RX_FIFO_Siz)     
            US1_RX_FIFO_head = 0;                  
        US1_RX_FIFO_user++;
    }
    else
    {
        return RXbuff_overflow;
    }
   
    return 0;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
31条回答
shangdawei
2019-12-26 05:28

POSIX优化实现


  1. #include <sys/mman.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>

  4. #define report_exceptional_condition() abort ()

  5. struct ring_buffer
  6. {
  7.   void * address;

  8.   unsigned long count_bytes;
  9.   unsigned long write_offset_bytes;
  10.   unsigned long read_offset_bytes;
  11. };

  12. //Warning order should be at least 12 for Linux
  13. void ring_buffer_create( struct ring_buffer * buffer, unsigned long order )
  14. {
  15.   char path[ ] = "/dev/shm/ring-buffer-XXXXXX";
  16.   int file_descriptor;
  17.   void * address;
  18.   int status;

  19.   file_descriptor = mkstemp( path );
  20.   if ( file_descriptor < 0 )
  21.     report_exceptional_condition();

  22.   status = unlink( path );
  23.   if ( status )
  24.     report_exceptional_condition();

  25.   buffer->count_bytes = 1UL << order;
  26.   buffer->write_offset_bytes = 0;
  27.   buffer->read_offset_bytes = 0;

  28.   status = ftruncate( file_descriptor, buffer->count_bytes );
  29.   if ( status )
  30.     report_exceptional_condition();

  31.   buffer->address = mmap( NULL, buffer->count_bytes << 1, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE,  - 1, 0 );

  32.   if ( buffer->address == MAP_FAILED )
  33.     report_exceptional_condition();

  34.   address = mmap( buffer->address, buffer->count_bytes, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, file_descriptor,
  35.     0 );

  36.   if ( address != buffer->address )
  37.     report_exceptional_condition();

  38.   address = mmap( buffer->address + buffer->count_bytes, buffer->count_bytes, PROT_READ | PROT_WRITE, MAP_FIXED |
  39.     MAP_SHARED, file_descriptor, 0 );

  40.   if ( address != buffer->address + buffer->count_bytes )
  41.     report_exceptional_condition();

  42.   status = close( file_descriptor );
  43.   if ( status )
  44.     report_exceptional_condition();
  45. }

  46. void ring_buffer_free( struct ring_buffer * buffer )
  47. {
  48.   int status;

  49.   status = munmap( buffer->address, buffer->count_bytes << 1 );
  50.   if ( status )
  51.     report_exceptional_condition();
  52. }

  53. void * ring_buffer_write_address( struct ring_buffer * buffer )
  54. {
  55.   /*** void pointer arithmetic is a constraint violation. ***/
  56.   return buffer->address + buffer->write_offset_bytes;
  57. }

  58. void ring_buffer_write_advance( struct ring_buffer * buffer, unsigned long count_bytes )
  59. {
  60.   buffer->write_offset_bytes += count_bytes;
  61. }

  62. void * ring_buffer_read_address( struct ring_buffer * buffer )
  63. {
  64.   return buffer->address + buffer->read_offset_bytes;
  65. }

  66. void ring_buffer_read_advance( struct ring_buffer * buffer, unsigned long count_bytes )
  67. {
  68.   buffer->read_offset_bytes += count_bytes;

  69.   if ( buffer->read_offset_bytes >= buffer->count_bytes )
  70.   {
  71.      /*如果读指针大于等于缓冲区长度,那些读写指针同时折返回[0, buffer_size]范围内  */
  72.     buffer->read_offset_bytes -= buffer->count_bytes;
  73.     buffer->write_offset_bytes -= buffer->count_bytes;
  74.   }
  75. }

  76. unsigned long ring_buffer_count_bytes( struct ring_buffer * buffer )
  77. {
  78.   return buffer->write_offset_bytes - buffer->read_offset_bytes;
  79. }

  80. unsigned long ring_buffer_count_free_bytes( struct ring_buffer * buffer )
  81. {
  82.   return buffer->count_bytes - ring_buffer_count_bytes( buffer );
  83. }

  84. void ring_buffer_clear( struct ring_buffer * buffer )
  85. {
  86.   buffer->write_offset_bytes = 0;
  87.   buffer->read_offset_bytes = 0;
  88. }

  89. /*
  90. * Note, that initial anonymous mmap() can be avoided - after initial mmap() for descriptor fd,
  91. * you can try mmap() with hinted address as (buffer->address + buffer->count_bytes)
  92. * and if it fails - another one with hinted address as (buffer->address - buffer->count_bytes).
  93. *
  94. * Make sure MAP_FIXED is not used in such case, as under certain situations it could end with segfault.
  95. * The advantage of such approach is, that it avoids requirement to map twice the amount
  96. * you need initially (especially useful e.g. if you want to use hugetlbfs and the allowed amount is limited)
  97. * and in context of gcc/glibc - you can avoid certain feature macros
  98. * (MAP_ANONYMOUS usually requires one of: _BSD_SOURCE, _SVID_SOURCE or _GNU_SOURCE).
  99. */
复制代码

一周热门 更多>