mirror of
https://gitee.com/dlmu-cone/bf_original_balance_chassis
synced 2026-07-24 11:37:45 +08:00
添加了can的发送超时控制,添加了所有application层的文档和注释
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "main.h"
|
||||
#include "memory.h"
|
||||
#include "stdlib.h"
|
||||
#include "bsp_dwt.h"
|
||||
|
||||
/* can instance ptrs storage, used for recv callback */
|
||||
// 在CAN产生接收中断会遍历数组,选出hcan和rxid与发生中断的实例相同的那个,调用其回调函数
|
||||
@@ -88,12 +89,15 @@ CANInstance *CANRegister(CAN_Init_Config_s *config)
|
||||
|
||||
/* @todo 目前似乎封装过度,应该添加一个指向tx_buff的指针,tx_buff不应该由CAN instance保存 */
|
||||
/* 如果让CANinstance保存txbuff,会增加一次复制的开销 */
|
||||
void CANTransmit(CANInstance *_instance)
|
||||
uint8_t CANTransmit(CANInstance *_instance,uint8_t timeout)
|
||||
{
|
||||
float dwt_start = DWT_GetTimeline_ms();
|
||||
while (HAL_CAN_GetTxMailboxesFreeLevel(_instance->can_handle) == 0) // 等待邮箱空闲
|
||||
;
|
||||
if (DWT_GetTimeline_ms() - dwt_start > timeout) // 超时
|
||||
return 0;
|
||||
// tx_mailbox会保存实际填入了这一帧消息的邮箱,但是知道是哪个邮箱发的似乎也没啥用
|
||||
HAL_CAN_AddTxMessage(_instance->can_handle, &_instance->txconf, _instance->tx_buff, &_instance->tx_mailbox);
|
||||
return 1; // 发送成功
|
||||
}
|
||||
|
||||
void CANSetDLC(CANInstance *_instance, uint8_t length)
|
||||
|
||||
@@ -56,9 +56,10 @@ void CANSetDLC(CANInstance *_instance, uint8_t length);
|
||||
/**
|
||||
* @brief transmit mesg through CAN device,通过can实例发送消息
|
||||
* 发送前需要向CAN实例的tx_buff写入发送数据
|
||||
*
|
||||
*
|
||||
* @param timeout 超时时间,单位为ms;后续改为us,获得更精确的控制
|
||||
* @param _instance* can instance owned by module
|
||||
*/
|
||||
void CANTransmit(CANInstance *_instance);
|
||||
uint8_t CANTransmit(CANInstance *_instance,uint8_t timeout);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
> TODO:
|
||||
>
|
||||
> 1. 增加数据帧的长度定义,使得收发更加灵活,而不是固定的8 bytes
|
||||
> 2. 增加自动检测ID冲突的log输出。
|
||||
> 1. 增加自动检测ID冲突的log输出。
|
||||
|
||||
## 使用说明
|
||||
|
||||
@@ -65,7 +64,7 @@ typedef void (*can_callback)(can_instance*);
|
||||
|
||||
```c
|
||||
void CANRegister(can_instance* instance, can_instance_config config);
|
||||
void CANTransmit(can_instance* _instance);
|
||||
uint8_t CANTransmit(can_instance* _instance, uint8_t timeout);
|
||||
```
|
||||
|
||||
`CANRegister`是用于初始化CAN实例的接口,module层的模块对象(也应当为一个结构体)内要包含一个`usart_instance`。调用时传入实例指针,以及用于初始化的config。`CANRegister`应当在module的初始化函数内被调用,推荐config采用以下的方式定义,更加直观明了:
|
||||
@@ -103,4 +102,10 @@ void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
||||
|
||||
- `HAL_CAN_RxFifo0MsgPendingCallback()`和`HAL_CAN_RxFifo1MsgPendingCallback()`都是对HAL的CAN回调函数的重定义(原本的callback是`__week`修饰的弱定义),当发生FIFO0或FIFO1有新消息到达的时候,对应的callback会被调用。`CANFIFOxCallback()`随后被前两者调用,并根据接收id和硬件中断来源(哪一个CAN硬件,CAN1还是CAN2)调用对应的instance的回调函数进行协议解析。
|
||||
|
||||
- 当有一个模块注册了多个can实例时,通过`CANInstance.id`,使用强制类型转换将其转换成对应模块的实例指针,就可以对不同的模块实例进行回调处理了。
|
||||
- 当有一个模块注册了多个can实例时,通过`CANInstance.id`,使用强制类型转换将其转换成对应模块的实例指针,就可以对不同的模块实例进行回调处理了。
|
||||
|
||||
## 注意事项
|
||||
|
||||
由于CAN总线自带发送检测,如果总线上没有挂载目标设备(接收id和发送报文相同的设备),那么CAN邮箱会被占满而无法发送。在`CANTransmit()`中会对CAN邮箱是否已满进行`while(1)`检查。当超出`timeout`之后函数会返回零,说明发送失败。
|
||||
|
||||
由于卡在`while(1)`处不断检查邮箱是否空闲,调用`CANTransmit()`的任务可能无法按时挂起,导致任务定时不精确。建议在没有连接CAN进行调试时,按需注释掉有关CAN发送的代码部分,或设定一个较小的`timeout`值,防止对其他需要精确定时的任务产生影响。
|
||||
Reference in New Issue
Block a user