<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    嵌入式 環形緩沖區的設計與實現

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接
    1. 環形緩沖區是嵌入式系統中十分重要的一種數據結構,比如在一個視頻處理的機制中,環形緩沖區就可以理解為數據碼流的通道,每一個通道都對應著一個環形緩沖區,這樣數據在讀取和寫入的時候都可以在這個緩沖區里循環進行,程序員可以根據自己需要的數據大小來決定自己使用的緩沖區大小。  
    2.   
    3.     環形緩沖區,顧名思義這個緩沖區是環形的,那么何謂環形這個意思也很好理解,就是用一個指針去訪問該緩沖區的最后一個內存位置的的后一位置時回到環形緩沖區的起點。類似一個環一樣。這樣形容就很好理解了,當然有辦法實現了。我在這里采用了2種方式實現了環形緩沖區,一個是用數組的方法,一個是用鏈表的方法。  
    4.   
    5.     數組是一塊連續的內存,所以順序訪問時只要根據下標的增加而增加,但是最后一個元素之后需要回到起始位置,這就需要我們對這個地方進行特殊處理。只要最后一個地址訪問結束能順利回到起始地址,這個緩沖區就可以實現。代碼如下:  
    6.   
    7. [cpp] view plaincopyprint?  
    8. 01./* File name: ringbuf.c   
    9. 02. * Author   : wanxiao   
    10. 03. * Function :Implement a circular buffer,    
    11. 04.             you can read and write data in the buffer zone.   
    12. 05. */    
    13. 06.    
    14. 07.#include <stdio.h>        
    15. 08.      
    16. 09.#define MAXSIZE 8        
    17. 10.      
    18. 11.int ringbuf[MAXSIZE];       
    19. 12.int readldx=0;    
    20. 13.int writeldx=0;    
    21. 14.    
    22. 15.int next_data_handle(int addr)       
    23. 16.{       
    24. 17.    return (addr+1) == MAXSIZE ? 0:(addr+1) ;       
    25. 18.}       
    26. 19.      
    27. 20.int write_data(int data)    
    28. 21.{    
    29. 22.    int i;    
    30. 23.    *(ringbuf+writeldx) = data;    
    31. 24.    writeldx = next_data_handle(writeldx);    
    32. 25.    for(i=0;i<MAXSIZE;i++)    
    33. 26.    {    
    34. 27.        printf("%4d",*(ringbuf+i));    
    35. 28.        if(MAXSIZE-1 == i)    
    36. 29.            printf("/n");    
    37. 30.    }    
    38. 31.}    
    39. 32.    
    40. 33.int read_data()    
    41. 34.{    
    42. 35.    printf("read data is : %d/n",*(ringbuf+readldx));    
    43. 36.    readldx = next_data_handle(readldx);    
    44. 37.}    
    45. 38.      
    46. 39.int main(int argc , char **argv)       
    47. 40.{       
    48. 41.    int data;       
    49. 42.    char cmd;    
    50. 43.    
    51. 44.    do{       
    52. 45.        printf("select:/nw/t--write/nr/t--read/nq/t--quit/n");       
    53. 46.        scanf("%s",&cmd);       
    54. 47.      
    55. 48.        switch(cmd)       
    56. 49.        {       
    57. 50.            case 'w' :       
    58. 51.                printf("please input data:");       
    59. 52.                scanf("%d",&data);       
    60. 53.                write_data(data);       
    61. 54.                break;       
    62. 55.            case 'r' :       
    63. 56.                data = read_data();       
    64. 57.                break;       
    65. 58.            case 'q' :       
    66. 59.                printf("quit/n");       
    67. 60.                break;       
    68. 61.            default :       
    69. 62.                printf("Command  error/n");       
    70. 63.        }       
    71. 64.    }while(cmd != 'q');       
    72. 65.    return 0;       
    73. 66.}    
    74. /* File name: ringbuf.c  
    75.  * Author   : wanxiao  
    76.  * Function :Implement a circular buffer,   
    77.              you can read and write data in the buffer zone.  
    78.  */  
    79.   
    80. #include <stdio.h>     
    81.     
    82. #define MAXSIZE 8     
    83.     
    84. int ringbuf[MAXSIZE];     
    85. int readldx=0;  
    86. int writeldx=0;  
    87.   
    88. int next_data_handle(int addr)     
    89. {     
    90.     return (addr+1) == MAXSIZE ? 0:(addr+1) ;     
    91. }     
    92.     
    93. int write_data(int data)  
    94. {  
    95.     int i;  
    96.     *(ringbuf+writeldx) = data;  
    97.     writeldx = next_data_handle(writeldx);  
    98.     for(i=0;i<MAXSIZE;i++)  
    99.     {  
    100.         printf("%4d",*(ringbuf+i));  
    101.         if(MAXSIZE-1 == i)  
    102.             printf("/n");  
    103.     }  
    104. }  
    105.   
    106. int read_data()  
    107. {  
    108.     printf("read data is : %d/n",*(ringbuf+readldx));  
    109.     readldx = next_data_handle(readldx);  
    110. }  
    111.     
    112. int main(int argc , char **argv)     
    113. {     
    114.     int data;     
    115.     char cmd;  
    116.   
    117.     do{     
    118.         printf("select:/nw/t--write/nr/t--read/nq/t--quit/n");     
    119.         scanf("%s",&cmd);     
    120.     
    121.         switch(cmd)     
    122.         {     
    123.             case 'w' :     
    124.                 printf("please input data:");     
    125.                 scanf("%d",&data);     
    126.                 write_data(data);     
    127.                 break;     
    128.             case 'r' :     
    129.                 data = read_data();     
    130.                 break;     
    131.             case 'q' :     
    132.                 printf("quit/n");     
    133.                 break;     
    134.             default :     
    135.                 printf("Command  error/n");     
    136.         }     
    137.     }while(cmd != 'q');     
    138.     return 0;     
    139. }  
    140.    
    141.   
    142.    
    143.   
    144.     鏈表實現,實際上就是一個單向循環鏈表。這個方法的優點是不需要最后一個元素進行特殊處理,但是實現起來比數組稍微麻煩一點,單思路還是很清晰簡單的。代碼如下:  
    145.   
    146. [cpp] view plaincopyprint?  
    147. 01.#include <stdio.h>     
    148. 02.#include <stdlib.h>     
    149. 03.    
    150. 04.    
    151. 05.typedef struct signal_loop_chain    
    152. 06.{    
    153. 07.    int data;    
    154. 08.    struct signal_loop_chain *next;    
    155. 09.}NODE;    
    156. 10.    
    157. 11.NODE *Create_loop_chain(int n)    
    158. 12.{    
    159. 13.    int i;    
    160. 14.    NODE *head , *previous , *current ;    
    161. 15.    previous = (NODE *)malloc(sizeof(NODE));    
    162. 16.    if(previous == NULL)    
    163. 17.        exit(1);    
    164. 18.    
    165. 19.    previous->data =0;    
    166. 20.    previous->next = NULL;    
    167. 21.    head = previous ;    
    168. 22.    
    169. 23.    for(i=0 ; i<n ; i++)    
    170. 24.    {    
    171. 25.        current = (NODE*)malloc(sizeof(NODE));    
    172. 26.        if(current == NULL)    
    173. 27.            exit(1);    
    174. 28.    
    175. 29.//      scanf("%d",¤t->data);     
    176. 30.        current->next = head;    
    177. 31.        previous->next = current;    
    178. 32.        previous = current ;    
    179. 33.    }    
    180. 34.    return head ;    
    181. 35.}    
    182. 36.    
    183. 37.int Show(NODE *head)    
    184. 38.{    
    185. 39.    NODE *current;    
    186. 40.    current = head->next ;    
    187. 41.    printf("List:/n");    
    188. 42.    while(current != head)    
    189. 43.    {    
    190. 44.        printf("%4d",current->data);    
    191. 45.        current = current->next;    
    192. 46.    }    
    193. 47.    printf("/n");    
    194. 48.}    
    195. 49.    
    196. 50.int read_buf(NODE *head)    
    197. 51.{    
    198. 52.    NODE *current;    
    199. 53.    current = head->next;    
    200. 54.    while(1)    
    201. 55.    {    
    202. 56.        printf("read number is %d/n",current->data);    
    203. 57.        current = current->next;    
    204. 58.        sleep(1);    
    205. 59.    }    
    206. 60.    
    207. 61.}    
    208. 62.    
    209. 63.int write_buf(NODE *head)    
    210. 64.{    
    211. 65.    NODE *current;    
    212. 66.    int i = 0;    
    213. 67.    current = head->next;    
    214. 68.    while(1)    
    215. 69.    {    
    216. 70.        current->data = i++;    
    217. 71.        printf("write number is %d/n",current->data);    
    218. 72.        current = current->next;    
    219. 73.        sleep(1);    
    220. 74.    }    
    221. 75.}    
    222. 76.    
    223. 77.int main(int argc , char **argv)    
    224. 78.{    
    225. 79.    int num;    
    226. 80.    char cmd;    
    227. 81.    NODE *head;    
    228. 82.    printf("please input node_num /n");    
    229. 83.    scanf("%d",&num);    
    230. 84.    head = Create_loop_chain(num);    
    231. 85.    printf("The ringbuf was found/n");    
    232. 86.    Show(head);    
    233. 87.    
    234. 88.    while(1){    
    235. 89.        printf("please select r or w/n");    
    236. 90.        scanf("%c",&cmd);    
    237. 91.    
    238. 92.        if(cmd == 'r'){    
    239. 93.            read_buf(head);    
    240. 94.            Show(head);    
    241. 95.        }    
    242. 96.            
    243. 97.        if(cmd == 'w'){    
    244. 98.            write_buf(head);    
    245. 99.            Show(head);    
    246. 100.        }    
    247. 101.            
    248. 102.    }    
    249. 103.    return 0;    
    250. 104.}    
    251. #include <stdio.h>  
    252. #include <stdlib.h>  
    253.   
    254.   
    255. typedef struct signal_loop_chain  
    256. {  
    257.     int data;  
    258.     struct signal_loop_chain *next;  
    259. }NODE;  
    260.   
    261. NODE *Create_loop_chain(int n)  
    262. {  
    263.     int i;  
    264.     NODE *head , *previous , *current ;  
    265.     previous = (NODE *)malloc(sizeof(NODE));  
    266.     if(previous == NULL)  
    267.         exit(1);  
    268.   
    269.     previous->data =0;  
    270.     previous->next = NULL;  
    271.     head = previous ;  
    272.   
    273.     for(i=0 ; i<n ; i++)  
    274.     {  
    275.         current = (NODE*)malloc(sizeof(NODE));  
    276.         if(current == NULL)  
    277.             exit(1);  
    278.   
    279. //      scanf("%d",¤t->data);  
    280.         current->next = head;  
    281.         previous->next = current;  
    282.         previous = current ;  
    283.     }  
    284.     return head ;  
    285. }  
    286.   
    287. int Show(NODE *head)  
    288. {  
    289.     NODE *current;  
    290.     current = head->next ;  
    291.     printf("List:/n");  
    292.     while(current != head)  
    293.     {  
    294.         printf("%4d",current->data);  
    295.         current = current->next;  
    296.     }  
    297.     printf("/n");  
    298. }  
    299.   
    300. int read_buf(NODE *head)  
    301. {  
    302.     NODE *current;  
    303.     current = head->next;  
    304.     while(1)  
    305.     {  
    306.         printf("read number is %d/n",current->data);  
    307.         current = current->next;  
    308.         sleep(1);  
    309.     }  
    310.   
    311. }  
    312.   
    313. int write_buf(NODE *head)  
    314. {  
    315.     NODE *current;  
    316.     int i = 0;  
    317.     current = head->next;  
    318.     while(1)  
    319.     {  
    320.         current->data = i++;  
    321.         printf("write number is %d/n",current->data);  
    322.         current = current->next;  
    323.         sleep(1);  
    324.     }  
    325. }  
    326.   
    327. int main(int argc , char **argv)  
    328. {  
    329.     int num;  
    330.     char cmd;  
    331.     NODE *head;  
    332.     printf("please input node_num /n");  
    333.     scanf("%d",&num);  
    334.     head = Create_loop_chain(num);  
    335.     printf("The ringbuf was found/n");  
    336.     Show(head);  
    337.   
    338.     while(1){  
    339.         printf("please select r or w/n");  
    340.         scanf("%c",&cmd);  
    341.   
    342.         if(cmd == 'r'){  
    343.             read_buf(head);  
    344.             Show(head);  
    345.         }  
    346.           
    347.         if(cmd == 'w'){  
    348.             write_buf(head);  
    349.             Show(head);  
    350.         }  
    351.           
    352.     }  
    353.     return 0;  
    354. }  
    355.    
    356.   
    357.    
    358.   
    359.    
    360.   
    361.    
    362.   
    363.     以上都是針對單進程而言。對于系統,尤其是嵌入式Linux系統中,緩沖區的保護機制就變得尤為重要了,因為我們的數據時不停的在讀寫,內存不停的變化,如果牽扯到多任務(多進程,多線程),我們就需要加鎖對其進行保護措施。這里我在鏈表的實現下加了信號量加以保護。  
    364.   
    365. [c-sharp] view plaincopyprint?  
    366. 01.#include <stdio.h>    
    367. 02.#include <stdlib.h>    
    368. 03.#include <pthread.h>    
    369. 04.#include <semaphore.h>     
    370. 05.    
    371. 06.sem_t mutex;    
    372. 07.    
    373. 08.typedef struct signal_loop_chain    
    374. 09.{    
    375. 10.    int data;    
    376. 11.    struct signal_loop_chain *next;    
    377. 12.}NODE;    
    378. 13.    
    379. 14.NODE *Create_loop_chain(int n)    
    380. 15.{    
    381. 16.    int i;    
    382. 17.    NODE *head , *previous , *current ;    
    383. 18.    previous = (NODE *)malloc(sizeof(NODE));    
    384. 19.    if(previous == NULL)    
    385. 20.        exit(1);    
    386. 21.    
    387. 22.    previous->data =0;    
    388. 23.    previous->next = NULL;    
    389. 24.    head = previous ;    
    390. 25.    
    391. 26.    for(i=0 ; i<n ; i++)    
    392. 27.    {    
    393. 28.        current = (NODE*)malloc(sizeof(NODE));    
    394. 29.        if(current == NULL)    
    395. 30.            exit(1);    
    396. 31.    
    397. 32.        current->next = head;    
    398. 33.        previous->next = current;    
    399. 34.        previous = current ;    
    400. 35.    }    
    401. 36.    return head ;    
    402. 37.}    
    403. 38.    
    404. 39.int Show(NODE *head)    
    405. 40.{    
    406. 41.    NODE *current;    
    407. 42.    current = head->next ;    
    408. 43.    printf("List:/n");    
    409. 44.    while(current != head)    
    410. 45.    {    
    411. 46.        printf("%4d",current->data);    
    412. 47.        current = current->next;    
    413. 48.    }    
    414. 49.    printf("/n");    
    415. 50.}    
    416. 51.    
    417. 52.int read_buf(NODE *head)    
    418. 53.{    
    419. 54.    NODE *current;    
    420. 55.    current = head->next;    
    421. 56.    while(1)    
    422. 57.    {    
    423. 58.        sem_wait(&mutex);    
    424. 59.        printf("read number is %d/n",current->data);    
    425. 60.        current = current->next;    
    426. 61.        sem_post(&mutex);    
    427. 62.        sleep(2);    
    428. 63.    }    
    429. 64.    
    430. 65.}    
    431. 66.    
    432. 67.int write_buf(NODE *head)    
    433. 68.{    
    434. 69.    NODE *current;    
    435. 70.    int i = 0;    
    436. 71.    current = head->next;    
    437. 72.    while(1)    
    438. 73.    {    
    439. 74.        sem_wait(&mutex);    
    440. 75.        current->data = i++;    
    441. 76.        printf("write number is %d/n",current->data);    
    442. 77.        current = current->next;    
    443. 78.        sem_post(&mutex);    
    444. 79.        sleep(1);    
    445. 80.    }    
    446. 81.}    
    447. 82.    
    448. 83.int main(int argc , char **argv)    
    449. 84.{    
    450. 85.    int num,ret;    
    451. 86.    char cmd;    
    452. 87.    NODE *head;    
    453. 88.    pthread_t id1,id2;    
    454. 89.    
    455. 90.    ret = sem_init(&mutex ,0,1);    
    456. 91.    if(ret != 0){    
    457. 92.        perror("sem_init error");    
    458. 93.    }    
    459. 94.    printf("please input node_num /n");    
    460. 95.    scanf("%d",&num);    
    461. 96.    head = Create_loop_chain(num);    
    462. 97.    printf("The ringbuf was found/n");    
    463. 98.    Show(head);    
    464. 99.    
    465. 100.    ret = pthread_create(&id1,NULL,(void *)write_buf,head);    
    466. 101.    ret = pthread_create(&id2,NULL,(void *)read_buf,head);    
    467. 102.    
    468. 103.    pthread_join(id1,NULL);    
    469. 104.    pthread_join(id2,NULL);    
    470. 105.        
    471. 106.    
    472. 107.    return 0;    
    473. 108.}    
    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全