添加了can的发送超时控制,添加了所有application层的文档和注释

This commit is contained in:
NeoZng
2023-01-03 22:53:49 +08:00
parent f37d813bcd
commit 48370d4411
16 changed files with 160 additions and 40 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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`值,防止对其他需要精确定时的任务产生影响。