|
- template<class U>
- class queue{
- protected:
- int deIndex;
- int enIndex;
- U* items;
- int itemMax;
- bool freeMem;
-
- public:
- queue(int count){
- Init(count);
- }
- queue(U* buff,int count){
- Init(buff,count);
- }
- queue(){
- enIndex = 0;
- deIndex = 0;
- itemMax = 0;
- freeMem = false;
- }
- ~queue(){
- itemMax = 0;
- if(freeMem){
- delete[] items;
- }
- enIndex = 0;
- deIndex = 0;
- freeMem = false;
- }
- void Init(int count){
- enIndex = 0;
- deIndex = 0;
- items = new U[count];
- freeMem = true;
- itemMax = count;
- }
- void Init(U* buff,int count){
- enIndex = 0;
- deIndex = 0;
- items = buff;
- freeMem = false;
- itemMax = count;
- }
- void Clear(void){
- deIndex = enIndex;
- }
- int CountToWrite(void){
- if(itemMax == 0){
- return 0;
- }
- return itemMax - CountToRead() - 1;
- }
- int CountToRead(void){
- int c = 0;
- volatile int deIndex_bak;
- volatile int enIndex_bak;
- deIndex_bak = deIndex;
- enIndex_bak = enIndex;
- if(deIndex_bak > enIndex_bak){
- c = (itemMax - deIndex_bak) + enIndex_bak;
- }else{
- c = enIndex_bak - deIndex_bak;
- }
- return c;
- }
- int UseRate(void){
- int x = CountToRead();
- int y = itemMax;
- if(y == 0){
- return 100;
- }
- return (x*100)/y;
- }
- int EnQueue(U& item){
- volatile int x;
- if(CountToWrite()){
- x = enIndex;
- items[x++] = item;
- if(x >= itemMax){
- x = 0;
- }
- enIndex = x;
- return 1;
- }
- return 0;
- }
- int EnQueue(U buf[],int count){
- volatile int x;
- x = CountToWrite();
- if(x < count){
- count = x;
- }
- x = enIndex;
- for(int i = 0;i < count;i++){
- items[x++] = buf[i];
- if(x >= itemMax){
- x = 0;
- }
- }
- enIndex = x;
- return count;
- }
- U DeQueue(void){
- volatile int i=0,x;
- if(CountToRead()){
- x = deIndex;
- i = deIndex;
- x++;
- if(x >= itemMax){
- x = 0;
- }
- deIndex = x;
- }
- return items[i];
- }
- int DeQueue(U& item){
- volatile int x;
- if(CountToRead()){
- x = deIndex;
- item = items[x++];
- if(x >= itemMax){
- x = 0;
- }
- deIndex = x;
- return 1;
- }
- return 0;
- }
- int DeQueue(U buf[],int count){
- volatile int x;
- x = CountToRead();
- if(x < count){
- count = x;
- }
- x = deIndex;
- for(int i = 0;i < count;i++){
- buf[i] = items[x++];
- if(x >= itemMax){
- x = 0;
- }
- }
- deIndex = x;
- return count;
- }
- int Count(void){
- return CountToRead();
- }
- };
- // 假设这是CAN消息数据类型定义,使用了ARMCC的匿名联合属性
- #pragma push
- #pragma anon_unions
- union CAN_Message{
- struct{
- unsigned int DA;
- unsigned int DB;
- unsigned int ID;
- unsigned char format; // 0 - STANDARD, 1- EXTENDED IDENTIFIER
- unsigned char type; // 0 - DATA FRAME, 1 - REMOTE FRAME
- unsigned char len;
- unsigned char ctrl;
- };
- struct{
- short v0;
- short v1;
- short v2;
- short v3;
- unsigned int id;
- unsigned int ftlc;
- };
- unsigned char buff[16];
- unsigned char data[16];
- unsigned short v16[4];
-
- CAN_Message(){
- DA = 0;
- DB = 0;
- ID = 0;
- ftlc = 0;
- }
- CAN_Message(const CAN_Message& t){
- DA = t.DA;
- DB = t.DB;
- ID = t.ID;
- ftlc = t.ftlc;
- }
- CAN_Message& operator=(const CAN_Message& t){
- DA = t.DA;
- DB = t.DB;
- ID = t.ID;
- ftlc = t.ftlc;
- return *this;
- }
- };
- #pragma pop
- // 使用例子
- // 定义一个CAN_Message队列,使用自动分配内存,队列能容纳99个CAN_Message
- queue<CAN_Message> CanReceiveQueue(100);
- // 或者
- CAN_Message CanReceiveBuf[100];
- queue<CAN_Message> CanReceiveQueue(CanReceiveBuf,100);
- // 假设这是CAN接收回调函数,一般是在中断调用的
- void CAN_ReceiveCallBack(CAN_Message & msg){
- if (CanReceiveQueue.CountToWrite()) {
- CanReceiveQueue.EnQueue(msg);
- }
- }
- int main(void){
- CAN_Message msg1;
-
- // 环境初始化...
-
- while(true){
- // 打印接收到的CAN报文
- if(CanReceiveQueue.CountToRead()){
- CanReceiveQueue.DeQueue(msg1);
- printf("from:CAN%l,len=%l,id=%8XL | ",msg1.ctrl,msg1.len,msg1.ID);
- for(int i = 0;i < msg1.len;i++){
- printf("%'02XL,",msg1.buff[i]);
- }
- printf("\n");
- }
- }
- /*
- note:
- 对于复杂数据类型,一定要实现[拷贝构造函数]与[operator=运算符]才能放入queue.
- 其它数据类型如int,short,char可随便使用
- 如: queue<int> q1;
- q1.Init(count);
- 关于线程安全性:
- 使用queue时,必须要考虑线程安全性,如:中断与任务,任务与任务之间.
- 当在中断中入队时,不要有其它地方也做入队操作,出队也是同理
- 入队操作与出队操作之间不存在线程安全问题!
- 当有多个任务需要对队列做相同操作时,请封装queue,并使用mutex,此处略
- 另外,有些人把queue与RTOS绑在一起,搞的好像RTOS好厉害的样子,简直误人子弟!
- */
复制代码
|
|