基于RingBufferCan数据接收的高速缓冲区。
使用RIngbuffer的原因:
- RIngbuffer的基础结构是一段连续的内存,可以通过指针偏移的方式快速访问。
接口- 头文件 canRing.h
讲在前头’‘‘your_save_data_struct’’'是自己定义的数据结构的类型。
#ifndef __CAN_RING_H__
#define __CAN_RING_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
void can_ring_init(void);
void msg_read_by_ring(int chanl, your_save_data_struct* msg);
void msg_write_to_ring(int chanl, your_save_data_struct* msg);
#ifdef __cplusplus
}
#endif
#endif //CanRing.h
source 文件
#include "CanRing.h"
#include <stdlib.h>
#include <string.h>
#define CanMsgMaxLineNum 8 //单行可存储的can msg的条数
#define CanMsgMaxEntryNum 25 //每一路can ring的深度
#define CanChannelMaxNum 1U //can的通道数量
typedef struct RADERMSGRING{
int line_num;
int mutex_lock;
your_save_data_struct *write_ptr;
your_save_data_struct *read_ptr;
your_save_data_struct *line_head_ptr[CanMsgMaxLineNum];
your_save_data_struct *line_tail_ptr[CanMsgMaxLineNum];
}can_ring_ctrl;
can_ring_ctrl can_msg_Ring[CanChannelMaxNum] = {0};
static your_save_data_struct CanMsgRcvPool[CanChannelMaxNum][CanMsgMaxLineNum*CanMsgMaxEntryNum] = {0};
int Start_flag = 0;
void can_ring_init(void)
{
int i, j;
for(i=0;i<CanChannelMaxNum;i++){
can_msg_Ring[i].line_num = 0;
can_msg_Ring[i].mutex_lock = 1;
can_msg_Ring[i].write_ptr = CanMsgRcvPool[i];
can_msg_Ring[i].read_ptr = CanMsgRcvPool[i];
for(j=0;j<CanMsgMaxLineNum;j++){
can_msg_Ring[i].line_head_ptr[j] = &CanMsgRcvPool[i][(j*CanMsgMaxEntryNum)];
can_msg_Ring[i].line_tail_ptr[j] = &CanMsgRcvPool[i][(((j+1)*(CanMsgMaxEntryNum))-1)];
}
}
}
void msg_read_by_ring(int chanl, your_save_data_struct* msg)
{
int copy_size = sizeof(your_save_data_struct) * CanMsgMaxEntryNum;
if(Start_flag == 0){
memset(msg, 0, copy_size);
printf("no msg to read\n");
return ;
}
if(can_msg_Ring[chanl].read_ptr == can_msg_Ring[chanl].line_head_ptr[can_msg_Ring[chanl].line_num]){
if(can_msg_Ring[chanl].mutex_lock){
can_msg_Ring[chanl].mutex_lock = 0;
can_msg_Ring[chanl].line_num++;
if(can_msg_Ring[chanl].line_num > CanMsgMaxLineNum){
can_msg_Ring[chanl].line_num = 0;
}
can_msg_Ring[chanl].write_ptr = can_msg_Ring[chanl].line_head_ptr[can_msg_Ring[chanl].line_num];
can_msg_Ring[chanl].mutex_lock = 1;
}
}
memcpy(msg, can_msg_Ring[chanl].read_ptr, copy_size);
memset(can_msg_Ring[chanl].read_ptr, 0, copy_size);
can_msg_Ring[chanl].read_ptr+=CanMsgMaxEntryNum; //next copy ptr
if(can_msg_Ring[chanl].read_ptr > can_msg_Ring[chanl].line_head_ptr[(CanMsgMaxLineNum-1)]){
can_msg_Ring[chanl].read_ptr = can_msg_Ring[chanl].line_head_ptr[0];//next copy ptr
}
}
void msg_write_to_ring(int chanl, your_save_data_struct* msg)
{
if(msg == NULL){
printf("msg_write_to_ring error msg is null ptr\n");
}
if(can_msg_Ring[chanl].mutex_lock){
can_msg_Ring[chanl].mutex_lock = 0;
memcpy( can_msg_Ring[chanl].write_ptr, msg, sizeof(your_save_data_struct));
can_msg_Ring[chanl].write_ptr++;
if( (can_msg_Ring[chanl].write_ptr ) > (can_msg_Ring[chanl].line_tail_ptr[can_msg_Ring[chanl].line_num])){
can_msg_Ring[chanl].line_num++;
if(can_msg_Ring[chanl].line_num > CanMsgMaxLineNum){
can_msg_Ring[chanl].line_num = 0;
}
can_msg_Ring[chanl].write_ptr = can_msg_Ring[chanl].line_head_ptr[can_msg_Ring[chanl].line_num];
}
can_msg_Ring[chanl].mutex_lock = 1;
Start_flag = 1;
}
}