7871|4

130

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

教你使用真正的queue [复制链接]


  1. template<class U>
  2. class queue{
  3.   protected:
  4.                 int         deIndex;
  5.                 int         enIndex;
  6.                 U*         items;
  7.                 int         itemMax;
  8.                 bool freeMem;        
  9.         
  10.   public:
  11.                 queue(int count){
  12.                         Init(count);        
  13.                 }
  14.                 queue(U* buff,int count){
  15.                         Init(buff,count);
  16.                 }
  17.                 queue(){
  18.                         enIndex = 0;
  19.                         deIndex = 0;
  20.                         itemMax = 0;
  21.                         freeMem = false;
  22.                 }
  23.                 ~queue(){
  24.                         itemMax = 0;
  25.                         if(freeMem){
  26.                                 delete[] items;
  27.                         }
  28.                         enIndex = 0;
  29.                         deIndex = 0;
  30.                         freeMem = false;
  31.                 }
  32.                 void Init(int count){        
  33.                         enIndex = 0;
  34.                         deIndex = 0;
  35.                         items = new U[count];
  36.                         freeMem = true;
  37.                         itemMax = count;        
  38.                 }
  39.                 void Init(U* buff,int count){
  40.                         enIndex = 0;
  41.                         deIndex = 0;
  42.                         items = buff;
  43.                         freeMem = false;        
  44.                         itemMax = count;                                
  45.                 }
  46.                 void Clear(void){
  47.                         deIndex = enIndex;
  48.                 }
  49.                 int CountToWrite(void){
  50.                         if(itemMax == 0){
  51.                                 return 0;
  52.                         }
  53.                         return itemMax - CountToRead() - 1;
  54.                 }
  55.                 int CountToRead(void){
  56.                         int c = 0;
  57.                         volatile int deIndex_bak;
  58.                         volatile int enIndex_bak;
  59.                         deIndex_bak = deIndex;
  60.                         enIndex_bak = enIndex;
  61.                         if(deIndex_bak > enIndex_bak){
  62.                                 c = (itemMax - deIndex_bak) + enIndex_bak;
  63.                         }else{
  64.                                 c = enIndex_bak - deIndex_bak;
  65.                         }
  66.                         return c;                        
  67.                 }
  68.                 int UseRate(void){
  69.                         int x = CountToRead();
  70.                         int y = itemMax;
  71.                         if(y == 0){
  72.                                 return 100;
  73.                         }
  74.                         return (x*100)/y;
  75.                 }
  76.                 int EnQueue(U& item){
  77.                         volatile int x;
  78.                         if(CountToWrite()){
  79.                                 x = enIndex;
  80.                                 items[x++] = item;
  81.                                 if(x >= itemMax){
  82.                                         x = 0;
  83.                                 }
  84.                                 enIndex = x;
  85.                                 return 1;
  86.                         }
  87.                         return 0;
  88.                 }
  89.                 int EnQueue(U buf[],int count){
  90.                         volatile int x;
  91.                         x = CountToWrite();
  92.                         if(x < count){
  93.                                 count = x;
  94.                         }
  95.                         x = enIndex;
  96.                         for(int i = 0;i < count;i++){
  97.                                 items[x++] = buf[i];        
  98.                                 if(x >= itemMax){
  99.                                         x = 0;
  100.                                 }
  101.                         }
  102.                         enIndex = x;
  103.                         return count;                        
  104.                 }
  105.                 U DeQueue(void){
  106.                         volatile int i=0,x;
  107.                         if(CountToRead()){
  108.                                 x = deIndex;
  109.                                 i = deIndex;        
  110.                                 x++;        
  111.                                 if(x >= itemMax){
  112.                                         x = 0;
  113.                                 }
  114.                                 deIndex = x;        
  115.                         }        
  116.                         return items[i];        
  117.                 }
  118.                 int DeQueue(U& item){
  119.                         volatile int x;
  120.                         if(CountToRead()){
  121.                                 x = deIndex;
  122.                                 item = items[x++];
  123.                                 if(x >= itemMax){
  124.                                         x = 0;
  125.                                 }
  126.                                 deIndex = x;               
  127.                                 return 1;        
  128.                         }
  129.                         return 0;
  130.                 }
  131.                 int DeQueue(U buf[],int count){
  132.                         volatile int x;
  133.                         x = CountToRead();
  134.                         if(x < count){
  135.                                 count = x;
  136.                         }
  137.                         x = deIndex;
  138.                         for(int i = 0;i < count;i++){
  139.                                 buf[i] = items[x++];
  140.                                 if(x >= itemMax){
  141.                                         x = 0;
  142.                                 }
  143.                         }
  144.                         deIndex = x;
  145.                         return count;                        
  146.                 }
  147.                 int Count(void){
  148.                         return CountToRead();
  149.                 }
  150. };

  151. // 假设这是CAN消息数据类型定义,使用了ARMCC的匿名联合属性
  152. #pragma push
  153. #pragma anon_unions
  154. union CAN_Message{
  155.         struct{
  156.                 unsigned int DA;
  157.                 unsigned int DB;
  158.                 unsigned int ID;
  159.                 unsigned char format; // 0 - STANDARD, 1- EXTENDED IDENTIFIER
  160.                 unsigned char type;   // 0 - DATA FRAME, 1 - REMOTE FRAME
  161.                 unsigned char len;               
  162.                 unsigned char ctrl;        
  163.         };
  164.         struct{
  165.                 short v0;
  166.                 short v1;
  167.                 short v2;
  168.                 short v3;
  169.                 unsigned int id;
  170.                 unsigned int ftlc;
  171.         };
  172.         unsigned char buff[16];
  173.         unsigned char data[16];
  174.         unsigned short v16[4];
  175.         
  176.         CAN_Message(){
  177.                 DA = 0;
  178.                 DB = 0;
  179.                 ID = 0;        
  180.                 ftlc = 0;
  181.         }
  182.         CAN_Message(const CAN_Message& t){
  183.                 DA = t.DA;
  184.                 DB = t.DB;
  185.                 ID = t.ID;
  186.                 ftlc = t.ftlc;
  187.         }
  188.         CAN_Message& operator=(const CAN_Message& t){
  189.                 DA = t.DA;
  190.                 DB = t.DB;
  191.                 ID = t.ID;
  192.                 ftlc = t.ftlc;
  193.                 return *this;
  194.         }
  195. };
  196. #pragma pop

  197. // 使用例子

  198. // 定义一个CAN_Message队列,使用自动分配内存,队列能容纳99个CAN_Message
  199. queue<CAN_Message> CanReceiveQueue(100);
  200. // 或者
  201. CAN_Message CanReceiveBuf[100];
  202. queue<CAN_Message> CanReceiveQueue(CanReceiveBuf,100);

  203. // 假设这是CAN接收回调函数,一般是在中断调用的
  204. void CAN_ReceiveCallBack(CAN_Message & msg){
  205.         if (CanReceiveQueue.CountToWrite()) {
  206.                 CanReceiveQueue.EnQueue(msg);
  207.         }
  208. }


  209. int main(void){
  210.         CAN_Message msg1;
  211.         
  212.         // 环境初始化...
  213.         
  214.         while(true){               
  215.                 // 打印接收到的CAN报文
  216.                 if(CanReceiveQueue.CountToRead()){
  217.                         CanReceiveQueue.DeQueue(msg1);        
  218.                         printf("from:CAN%l,len=%l,id=%8XL | ",msg1.ctrl,msg1.len,msg1.ID);
  219.                         for(int i = 0;i < msg1.len;i++){
  220.                                 printf("%'02XL,",msg1.buff[i]);
  221.                         }               
  222.                         printf("\n");               
  223.         }
  224. }


  225. /*
  226. note:
  227.         对于复杂数据类型,一定要实现[拷贝构造函数]与[operator=运算符]才能放入queue.
  228.         其它数据类型如int,short,char可随便使用
  229.          如: queue<int> q1;
  230.              q1.Init(count);

  231.         关于线程安全性:
  232.         使用queue时,必须要考虑线程安全性,如:中断与任务,任务与任务之间.
  233.         当在中断中入队时,不要有其它地方也做入队操作,出队也是同理
  234.         入队操作与出队操作之间不存在线程安全问题!
  235.         当有多个任务需要对队列做相同操作时,请封装queue,并使用mutex,此处略

  236. 另外,有些人把queue与RTOS绑在一起,搞的好像RTOS好厉害的样子,简直误人子弟!
  237. */

复制代码


最新回复

楼主,辛苦了  详情 回复 发表于 2016-5-23 08:11
点赞 关注(1)

回复
举报

1976

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 
C++的不懂,我一般用来作通信的FIFO
 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

板凳
 
uart的发送与接收,can,tcp/ip协议栈,等等,都离不开queue
 
 
 

回复

954

帖子

0

TA的资源

纯净的硅(初级)

4
 
楼主既然写了,不如把线程安全的无锁队列也写一下,还有多对多的cas,不知道arm里米有这样的指令
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

5
 
楼主,辛苦了
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表