修复CAN中断优先级导致函数重入访问static变量的问题,提升了bsp和部分module的性能。

This commit is contained in:
NeoZng
2023-03-23 18:22:24 +08:00
parent eefc0883ed
commit 41d033e3f8
16 changed files with 76 additions and 65 deletions

View File

@@ -72,7 +72,8 @@ static void MotorSenderGrouping(DJIMotorInstance *motor, CAN_Init_Config_s *conf
if (dji_motor_instance[i]->motor_can_instance->can_handle == config->can_handle && dji_motor_instance[i]->motor_can_instance->rx_id == config->rx_id)
{
LOGERROR("[dji_motor] ID crash. Check in debug mode, add dji_motor_instance to watch to get more information."); // 后续可以把id和CAN打印出来
while (1); // 6020的id 1-4和2006/3508的id 5-8会发生冲突(若有注册,即1!5,2!6,3!7,4!8) (1!5!,LTC! (((不是)
while (1)
; // 6020的id 1-4和2006/3508的id 5-8会发生冲突(若有注册,即1!5,2!6,3!7,4!8) (1!5!,LTC! (((不是)
}
}
break;
@@ -99,7 +100,8 @@ static void MotorSenderGrouping(DJIMotorInstance *motor, CAN_Init_Config_s *conf
if (dji_motor_instance[i]->motor_can_instance->can_handle == config->can_handle && dji_motor_instance[i]->motor_can_instance->rx_id == config->rx_id)
{
LOGERROR("[dji_motor] ID crash. Check in debug mode, add dji_motor_instance to watch to get more information.");
while (1); // 6020的id 1-4和2006/3508的id 5-8会发生冲突(若有注册,即1!5,2!6,3!7,4!8)
while (1)
; // 6020的id 1-4和2006/3508的id 5-8会发生冲突(若有注册,即1!5,2!6,3!7,4!8)
}
}
break;
@@ -118,13 +120,10 @@ static void MotorSenderGrouping(DJIMotorInstance *motor, CAN_Init_Config_s *conf
*/
static void DecodeDJIMotor(CANInstance *_instance)
{
// 由于需要多次变址访存,直接将buff和measure地址保存在寄存器里避免多次存取
static uint8_t *rxbuff;
static DJI_Motor_Measure_s *measure;
rxbuff = _instance->rx_buff;
// 这里对can instance的id进行了强制转换,从而获得电机的instance实例地址
// _instance指针指向的id是对应电机instance的地址,通过强制转换为电机instance的指针,再通过->运算符访问电机的成员motor_measure,最后取地址获得指针
measure = &(((DJIMotorInstance *)_instance->id)->motor_measure); // measure要多次使用,保存指针减小访存开销
uint8_t *rxbuff = _instance->rx_buff;
DJI_Motor_Measure_s *measure = &(((DJIMotorInstance *)_instance->id)->motor_measure); // measure要多次使用,保存指针减小访存开销
// 解析数据并对电流和速度进行滤波,电机的反馈报文具体格式见电机说明手册
measure->last_ecd = measure->ecd;
@@ -188,7 +187,7 @@ void DJIMotorChangeFeed(DJIMotorInstance *motor, Closeloop_Type_e loop, Feedback
}
else
{
LOGERROR("[dji_motor] loop type error, check memory access and func param");// 检查是否传入了正确的LOOP类型,或发生了指针越界
LOGERROR("[dji_motor] loop type error, check memory access and func param"); // 检查是否传入了正确的LOOP类型,或发生了指针越界
}
}
@@ -217,15 +216,14 @@ void DJIMotorSetRef(DJIMotorInstance *motor, float ref)
// 为所有电机实例计算三环PID,发送控制报文
void DJIMotorControl()
{
// 预先通过静态变量定义避免反复释放分配栈空间,直接保存一次指针引用从而减小访存的开销
// 同样可以提高可读性
static uint8_t group, num; // 电机组号和组内编号
static int16_t set; // 电机控制CAN发送设定值
static DJIMotorInstance *motor;
static Motor_Control_Setting_s *motor_setting; // 电机控制参数
static Motor_Controller_s *motor_controller; // 电机控制器
static DJI_Motor_Measure_s *motor_measure; // 电机测量
static float pid_measure, pid_ref; // 电机PID测量值和设定值
// 直接保存一次指针引用从而减小访存的开销,同样可以提高可读性
uint8_t group, num; // 电机组号和组内编号
int16_t set; // 电机控制CAN发送设定值
DJIMotorInstance *motor;
Motor_Control_Setting_s *motor_setting; // 电机控制参数
Motor_Controller_s *motor_controller; // 电机控制
DJI_Motor_Measure_s *motor_measure; // 电机测量值
float pid_measure, pid_ref; // 电机PID测量值和设定
// 遍历所有电机实例,进行串级PID的计算并设置发送报文的值
for (size_t i = 0; i < idx; ++i)

View File

@@ -40,12 +40,9 @@ static float uint_to_float(int x_int, float x_min, float x_max, int bits)
*/
static void HTMotorDecode(CANInstance *motor_can)
{
static uint16_t tmp; // 用于暂存解析值,稍后转换成float数据,避免多次创建临时变量
static HTMotor_Measure_t *measure;
static uint8_t *rxbuff;
rxbuff = motor_can->rx_buff;
measure = &((HTMotorInstance *)motor_can->id)->motor_measure; // 将can实例中保存的id转换成电机实例的指针
uint16_t tmp; // 用于暂存解析值,稍后转换成float数据,避免多次创建临时变量
uint8_t *rxbuff = motor_can->rx_buff;
HTMotor_Measure_t *measure = &((HTMotorInstance *)motor_can->id)->motor_measure; // 将can实例中保存的id转换成电机实例的指针
measure->last_angle = measure->total_angle;
@@ -89,12 +86,12 @@ void HTMotorSetRef(HTMotorInstance *motor, float ref)
void HTMotorControl()
{
static float set, pid_measure, pid_ref;
static uint16_t tmp;
static HTMotorInstance *motor;
static HTMotor_Measure_t *measure;
static Motor_Control_Setting_s *setting;
static CANInstance *motor_can;
float set, pid_measure, pid_ref;
uint16_t tmp;
HTMotorInstance *motor;
HTMotor_Measure_t *measure;
Motor_Control_Setting_s *setting;
CANInstance *motor_can;
// 遍历所有电机实例,计算PID
for (size_t i = 0; i < idx; i++)

View File

@@ -13,8 +13,8 @@ static CANInstance *sender_instance; // 多电机发送时使用的caninstance(
*/
static void LKMotorDecode(CANInstance *_instance)
{
static LKMotor_Measure_t *measure;
static uint8_t *rx_buff;
LKMotor_Measure_t *measure;
uint8_t *rx_buff;
rx_buff = _instance->rx_buff;
measure = &(((LKMotorInstance *)_instance->id)->measure); // 通过caninstance保存的id获取对应的motorinstance
@@ -72,11 +72,11 @@ LKMotorInstance *LKMotorInit(Motor_Init_Config_s *config)
/* 第一个电机的can instance用于发送数据,向其tx_buff填充数据 */
void LKMotorControl()
{
static float pid_measure, pid_ref;
static int16_t set;
static LKMotorInstance *motor;
static LKMotor_Measure_t *measure;
static Motor_Control_Setting_s *setting;
float pid_measure, pid_ref;
int16_t set;
LKMotorInstance *motor;
LKMotor_Measure_t *measure;
Motor_Control_Setting_s *setting;
for (size_t i = 0; i < idx; ++i)
{

View File

@@ -82,7 +82,7 @@ void Servo_Motor_Type_Select(ServoInstance *Servo_Motor, int16_t mode)
*/
void ServeoMotorControl()
{
static ServoInstance *Servo_Motor;
ServoInstance *Servo_Motor;
for (size_t i = 0; i < servo_idx; i++)
{