mirror of
https://gitee.com/dlmu-cone/bf_original_balance_chassis
synced 2026-07-25 03:47:47 +08:00
修复消息队列野指针的bug和队列长度计算异常的错误
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -23,7 +23,8 @@
|
|||||||
"bsp_usart.h": "c",
|
"bsp_usart.h": "c",
|
||||||
"message_center.h": "c",
|
"message_center.h": "c",
|
||||||
"stddef.h": "c",
|
"stddef.h": "c",
|
||||||
"stm32_hal_legacy.h": "c"
|
"stm32_hal_legacy.h": "c",
|
||||||
|
"message_buffer.h": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.default.configurationProvider": "ms-vscode.makefile-tools",
|
"C_Cpp.default.configurationProvider": "ms-vscode.makefile-tools",
|
||||||
}
|
}
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
#include "robot.h"
|
#include "robot.h"
|
||||||
|
#include "message_center.h"
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
@@ -64,7 +65,13 @@ void MX_FREERTOS_Init(void);
|
|||||||
|
|
||||||
/* Private user code ---------------------------------------------------------*/
|
/* Private user code ---------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN 0 */
|
/* USER CODE BEGIN 0 */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float a;
|
||||||
|
uint8_t b;
|
||||||
|
uint32_t c;
|
||||||
|
/* data */
|
||||||
|
}good;
|
||||||
/* USER CODE END 0 */
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,6 +120,17 @@ int main(void)
|
|||||||
|
|
||||||
RobotInit();
|
RobotInit();
|
||||||
|
|
||||||
|
good asdf;
|
||||||
|
good asdfsadf;
|
||||||
|
good pub={.a=1,.b=2,.c=3};
|
||||||
|
Subscriber_t* s=SubRegister("test\0",sizeof(good));
|
||||||
|
Subscriber_t* ss=SubRegister("test\0",sizeof(good));
|
||||||
|
Publisher_t* p=PubRegister("test\0",sizeof(asdf));
|
||||||
|
PubPushMessage(p,&pub);
|
||||||
|
PubPushMessage(p,&pub);
|
||||||
|
volatile uint8_t d= SubGetMessage(s,&asdf);
|
||||||
|
d=SubGetMessage(s,&asdf);
|
||||||
|
d=SubGetMessage(ss,&asdfsadf);
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Call init function for freertos objects (in freertos.c) */
|
/* Call init function for freertos objects (in freertos.c) */
|
||||||
|
|||||||
91
README.md
91
README.md
@@ -52,15 +52,13 @@
|
|||||||
|
|
||||||
- TODO:
|
- TODO:
|
||||||
|
|
||||||
1. 添加pub-sub(订阅-发布消息机制)的支持,以进一步隔离不同的模块完成封装。
|
1. 增加模块离线/错误检测模块(官方例程中的`deteck_task`)。
|
||||||
2. 增加模块离线/错误检测模块(官方例程中的`deteck_task`)。
|
2. 增加超级电容模块
|
||||||
3. 增加超级电容模块
|
3. 增加步进电机模块
|
||||||
4. 增加步进电机模块
|
4. 增加裁判系统多机通信、UI绘制模块
|
||||||
5. 增加双板CAN通信模块
|
5. 增加舵机模块
|
||||||
6. 增加裁判系统接收、多机通信、UI绘制模块
|
6. 增加单点激光模块
|
||||||
7. 增加舵机模块
|
|
||||||
8. 增加单点激光模块
|
|
||||||
|
|
||||||
- 主要功能:实现对设备的封装
|
- 主要功能:实现对设备的封装
|
||||||
|
|
||||||
- 子文件与子文件夹
|
- 子文件与子文件夹
|
||||||
@@ -81,7 +79,7 @@
|
|||||||
|
|
||||||
- 函数:
|
- 函数:
|
||||||
|
|
||||||
.c中存放的相当于这个类的private函数,.h中的则相当于public。相似的driver的public函数应较为统一。由于通信格式,使用方法等的不同,不同通信设备在读取操作、数据格式上可能有所不同,这些不同应该在driver的内部处理。
|
.c中存放的static函数和static变量相当于这个类的private函数,.h中的则相当于public。相似的driver的public函数应较为统一。由于通信格式,使用方法等的不同,不同通信设备在读取操作、数据格式上可能有所不同,这些不同应该在driver的内部处理。**由于C语言没有对象的概念,对于通信类的module,不同的实例需要在module.c中保存一份指针,用于处理数据接收的解析。**
|
||||||
|
|
||||||
- 封装程度:
|
- 封装程度:
|
||||||
|
|
||||||
@@ -111,34 +109,50 @@ Module层主要存放的是类型定义和实例指针数组,在该层没有
|
|||||||
```shell
|
```shell
|
||||||
ROOT:.
|
ROOT:.
|
||||||
│ .gitignore # git版本管理忽略文件
|
│ .gitignore # git版本管理忽略文件
|
||||||
│ .mxproject # CubeMX项目文件
|
│ .mxproject # CubeMX项目文件
|
||||||
│ basic_framework.ioc # CubeMX初始化配置文件
|
│ basic_framework.ioc # CubeMX初始化配置文件
|
||||||
│ Makefile # 编译管理文件,为make命令的目标
|
│ Makefile # 编译管理文件,为make(mingw32-make)命令的目标
|
||||||
│ openocd.cfg # 用于OpenOCD调试使用的配置文件
|
│ openocd_dap.cfg # 用于OpenOCD调试使用的配置文件
|
||||||
|
│ openocd_jlink.cfg # 同上
|
||||||
│ README.md # 本说明文档
|
│ README.md # 本说明文档
|
||||||
│ startup_stm32f407xx.s # F407汇编启动文件
|
│ startup_stm32f407xx.s # F407汇编启动文件
|
||||||
│ STM32F407.svd # F407外设地址映射文件,用于调试
|
│ STM32F407.svd # F407外设地址映射文件,用于调试
|
||||||
│ STM32F407IGHx_FLASH.ld # F407IGH(C板使用的MCU)的文件目标FLASH地址,用于烧录和调试
|
│ STM32F407IGHx_FLASH.ld # F407IGH(C板使用的MCU)的文件目标FLASH地址,用于烧录和调试
|
||||||
│ VSCode+Ozone使用方法.md # 开发环境配置
|
│ VSCode+Ozone使用方法.md # 开发环境配置和前置知识介绍
|
||||||
|
|
|
|
||||||
├─.vscode
|
├─.vscode
|
||||||
│ launch.json # 用于VSCode插件CORTEX-DEBUG调试的配置文件
|
│ launch.json # 用于VSCode插件CORTEX-DEBUG调试的配置文件
|
||||||
| task.json # 启动编译的任务配置文件
|
│ settings.json# 工作区配置文件,设置了代码缩进和format风格等
|
||||||
│
|
│ tasks.json # 启动编译的任务配置文件
|
||||||
├─assets # markdown存放图片和外链文件夹
|
├─assets # markdown存放图片和外链文件夹
|
||||||
|
|
|
|
||||||
├─application # 应用层,包括底盘控制,云台控制和发射控制
|
├─application
|
||||||
│ chassis.c
|
│ │ application.md
|
||||||
│ chassis.h
|
│ │ APP层应用编写指引.md
|
||||||
│ chassis.md
|
│ │ robot.c
|
||||||
│ gimbal.c
|
│ │ robot.h
|
||||||
│ gimbal.h
|
│ │ robot_def.h
|
||||||
│ gimbal.md
|
│ │
|
||||||
│ shoot.c
|
│ ├─chassis
|
||||||
│ shoot.h
|
│ │ chassis.c
|
||||||
│ shoot.md
|
│ │ chassis.h
|
||||||
| robot_cmd.c
|
│ │ chassis.md
|
||||||
| robot_cmd.h
|
│ │
|
||||||
|
│ ├─cmd
|
||||||
|
│ │ chassis_cmd.c
|
||||||
|
│ │ chassis_cmd.h
|
||||||
|
│ │ gimbal_cmd.c
|
||||||
|
│ │ gimbal_cmd.h
|
||||||
|
│ │
|
||||||
|
│ ├─gimbal
|
||||||
|
│ │ gimbal.c
|
||||||
|
│ │ gimbal.h
|
||||||
|
│ │ gimbal.md
|
||||||
|
│ │
|
||||||
|
│ └─shoot
|
||||||
|
│ shoot.c
|
||||||
|
│ shoot.h
|
||||||
|
│ shoot.md
|
||||||
│
|
│
|
||||||
├─bsp # 板级支持包,提供对硬件的封装,将接口暴露给module层
|
├─bsp # 板级支持包,提供对硬件的封装,将接口暴露给module层
|
||||||
│ bsp.md
|
│ bsp.md
|
||||||
@@ -149,7 +163,7 @@ ROOT:.
|
|||||||
│ bsp_can.md
|
│ bsp_can.md
|
||||||
│ bsp_dwt.c
|
│ bsp_dwt.c
|
||||||
│ bsp_dwt.h
|
│ bsp_dwt.h
|
||||||
│ bsp_init.c
|
│ bsp_init.c # bsp初始化
|
||||||
│ bsp_init.h
|
│ bsp_init.h
|
||||||
│ bsp_led.c
|
│ bsp_led.c
|
||||||
│ bsp_led.h
|
│ bsp_led.h
|
||||||
@@ -161,11 +175,14 @@ ROOT:.
|
|||||||
│ bsp_usart.c
|
│ bsp_usart.c
|
||||||
│ bsp_usart.h
|
│ bsp_usart.h
|
||||||
│ bsp_usart.md
|
│ bsp_usart.md
|
||||||
│ struct_typedef.h
|
|
||||||
│
|
│
|
||||||
├─HAL_N_Middlewares # HAL库对寄存器操作的封装,以及FreeRTOS等中间件
|
|
|
||||||
|
├─HAL_N_Middlewares # HAL库对寄存器操作的封装,以及FreeRTOS/Segger RTT等中间件
|
||||||
|
|
|
||||||
|
|
|
|
||||||
└─modules # 模块层,使用BSP提供的接口构建对应的功能模块,将模块实例提供给应用层
|
└─modules # 模块层,使用BSP提供的接口构建对应的功能模块,将模块实例提供给应用层
|
||||||
|
| module.md
|
||||||
|
|
|
||||||
├─algorithm # 算法
|
├─algorithm # 算法
|
||||||
│ algorithm.md
|
│ algorithm.md
|
||||||
│ controller.c # 控制器
|
│ controller.c # 控制器
|
||||||
@@ -209,6 +226,11 @@ ROOT:.
|
|||||||
│ seasky_protocol.h
|
│ seasky_protocol.h
|
||||||
│ 湖南大学RoboMaster电控组通信协议.md
|
│ 湖南大学RoboMaster电控组通信协议.md
|
||||||
│
|
│
|
||||||
|
├─message_center # 发布-订阅机制,app层应用之间交换数据用
|
||||||
|
│ message_center.c
|
||||||
|
│ message_center.h
|
||||||
|
│ message_center.md
|
||||||
|
|
|
||||||
├─motor # 电机模块
|
├─motor # 电机模块
|
||||||
│ dji_motor.c # DJI智能电机
|
│ dji_motor.c # DJI智能电机
|
||||||
│ dji_motor.h
|
│ dji_motor.h
|
||||||
@@ -231,8 +253,9 @@ ROOT:.
|
|||||||
│ remote_control.h
|
│ remote_control.h
|
||||||
│
|
│
|
||||||
└─super_cap # 超级电容
|
└─super_cap # 超级电容
|
||||||
super_cap.c
|
super_cap.c
|
||||||
super_cap.h
|
super_cap.h
|
||||||
|
super_cap.md
|
||||||
```
|
```
|
||||||
|
|
||||||
## BSP/Module/Application介绍
|
## BSP/Module/Application介绍
|
||||||
|
|||||||
@@ -101,8 +101,9 @@ Subscriber_t* SubRegister(char* name,uint8_t data_len)
|
|||||||
}
|
}
|
||||||
//遍历完,发现尚未注册事件,那么创建一个事件.此时node是publisher链表的最后一个结点
|
//遍历完,发现尚未注册事件,那么创建一个事件.此时node是publisher链表的最后一个结点
|
||||||
node->next_event_node=(Publisher_t*)malloc(sizeof(Publisher_t));
|
node->next_event_node=(Publisher_t*)malloc(sizeof(Publisher_t));
|
||||||
|
memset(node->next_event_node,0,sizeof(Publisher_t));
|
||||||
strcpy(node->next_event_node->event_name,name);
|
strcpy(node->next_event_node->event_name,name);
|
||||||
node->next_event_node->next_event_node=NULL; //新publisher的下一个节点置为NULL
|
node->next_event_node->data_len=data_len;
|
||||||
//创建subscriber作为新事件的第一个订阅者
|
//创建subscriber作为新事件的第一个订阅者
|
||||||
Subscriber_t* ret=(Subscriber_t*)malloc(sizeof(Subscriber_t));
|
Subscriber_t* ret=(Subscriber_t*)malloc(sizeof(Subscriber_t));
|
||||||
memset(ret,0,sizeof(Subscriber_t));
|
memset(ret,0,sizeof(Subscriber_t));
|
||||||
@@ -141,7 +142,7 @@ uint8_t SubGetMessage(Subscriber_t* sub,void* data_ptr)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy(sub->queue[sub->front_idx],data_ptr,sub->data_len);
|
memcpy(data_ptr,sub->queue[sub->front_idx],sub->data_len);
|
||||||
sub->front_idx=(sub->front_idx++)%QUEUE_SIZE;
|
sub->front_idx=(sub->front_idx++)%QUEUE_SIZE;
|
||||||
sub->temp_size--;
|
sub->temp_size--;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -149,19 +150,19 @@ uint8_t SubGetMessage(Subscriber_t* sub,void* data_ptr)
|
|||||||
|
|
||||||
void PubPushMessage(Publisher_t* pub,void* data_ptr)
|
void PubPushMessage(Publisher_t* pub,void* data_ptr)
|
||||||
{
|
{
|
||||||
static Subscriber_t* node;
|
pub->iter=pub->first_subs;
|
||||||
node->next_subs_queue=pub->first_subs;
|
while (pub->iter) //遍历订阅了当前事件的所有订阅者,依次填入最新消息
|
||||||
while (node->next_subs_queue) //遍历订阅了当前事件的所有订阅者,依次填入最新消息
|
|
||||||
{
|
{
|
||||||
node=node->next_subs_queue;
|
if(pub->iter->temp_size==QUEUE_SIZE) //如果队列已满,则需要删除最老的数据(头部),再填入
|
||||||
if(node->temp_size==QUEUE_SIZE) //如果队列已满,则需要删除最老的数据(头部),再填入
|
|
||||||
{ //头索引增加,相当于移动到新一个位置上
|
{ //头索引增加,相当于移动到新一个位置上
|
||||||
node->front_idx=(node->front_idx+1)%QUEUE_SIZE;
|
pub->iter->front_idx=(pub->iter->front_idx+1)%QUEUE_SIZE;
|
||||||
node->temp_size--; //相当于出队,size-1
|
pub->iter->temp_size--; //相当于出队,size-1
|
||||||
}
|
}
|
||||||
// 将Pub的数据复制到队列的尾部(最新)
|
// 将Pub的数据复制到队列的尾部(最新)
|
||||||
memcpy(node->queue[node->back_idx],data_ptr,pub->data_len);
|
memcpy(pub->iter->queue[pub->iter->back_idx],data_ptr,pub->data_len);
|
||||||
node->back_idx=(node->back_idx+1)%QUEUE_SIZE; //队列尾部前移
|
pub->iter->back_idx=(pub->iter->back_idx+1)%QUEUE_SIZE; //队列尾部前移
|
||||||
node->temp_size++; //入队,size+1
|
pub->iter->temp_size++; //入队,size+1
|
||||||
|
|
||||||
|
pub->iter=pub->iter->next_subs_queue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,6 +73,7 @@ typedef struct ent
|
|||||||
uint8_t data_len;
|
uint8_t data_len;
|
||||||
/* 指向第一个订阅了该事件的订阅者,通过链表访问所有订阅者 */
|
/* 指向第一个订阅了该事件的订阅者,通过链表访问所有订阅者 */
|
||||||
Subscriber_t* first_subs;
|
Subscriber_t* first_subs;
|
||||||
|
Subscriber_t* iter;// 用于遍历所有订阅了该事件的订阅者的指针
|
||||||
/* 指向下一个Publisher的指针 */
|
/* 指向下一个Publisher的指针 */
|
||||||
struct ent* next_event_node;
|
struct ent* next_event_node;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user