基线:PTG2.4
其它基线文件路径可能不同,find下文件名
以CANFD的demo为例(硬件端口CAN2),编译其它demo做法几乎一样。
1.CANFD demo路径
safety域有关于can发送数据的demo,位置在
source\lk_safety\application\sample\can\can_sample.c
2.编译的宏定义
can_sample默认没有被编译,需要添加编译的宏
source/lk_safety/application/rules.mk,rules.mk在sample目录的同级目录
ifeq ($(SUPPORT_CAN_SAMPLE_CODE), true)
MODULE_DEPS += application/sample/can
endif
需要编译的demo在rules.mk中找下有没有定义编译选项,没有的话仿照里面的demo添加一个
3.添加宏的位置
source/lk_safety/project/safety-v9156-ms.mk
SUPPORT_CAN_SAMPLE_CODE := true //编译demo
SUPPORT_CAN_SDDRV := true //编译依赖的文件
4.加入开机启动(非必须,根据实际需求来)
/*添加头文件*/
#include <app.h>
/*注释掉原来命令行启动部分*/
#if 0
//#if defined(WITH_LIB_CONSOLE)
STATIC_COMMAND_START
STATIC_COMMAND("can_sample", "can sample once", (console_cmd)&can_sample)
STATIC_COMMAND_END(can);
#endif
/*添加下列代码开机启动*/
APP_START(can_sample)
.entry = (app_entry)can_sample,
APP_END
通过阅读代码,会发现调用can接口非常容易,入门非常快,就几行代码。对没接触过芯弛芯片的同学来说也会很快上手。
5.检查GPIO配置
6.canfd的参数配置
yocto/source/lk_safety/chipdev/can/flexcan/can_cfg.c
{
.controllerId = CAN2,
.baseAddr = (uint32)APB_CAN2_BASE,
.irq_num = CANFD2_IPI_INT_MBOR_NUM,
.flexcanCfg = {
.clkSrc = FLEXCAN_ClkSrcPeri, /* 80MHz */
.maxMbNum = 14U,
.enableSelfWakeup = true,
.enableIndividMask = true,
.enableCANFD = true,
BAUDRATE_1M_5M,
#ifdef CAN_ENABLE_LOOPBACK
.enableLoopBack = true,
#endif
.can_fd_cfg = {
.enableISOCANFD = true,
.enableBRS = true,
.enableTDC = true,
.TDCOffset = 8U,
.r0_mb_data_size = CAN_FD_64BYTES_PER_MB,
.r1_mb_data_size = CAN_FD_64BYTES_PER_MB
}
}
},
通过配置文件可以看出can工具参数应该如何设置
7.关于如何测试上电can第一帧数据发出时间
7.1粗略计算:
设置串口工具,保存的每一行log前面加时间戳
连上safety域的串口可以记录开机的串口log,从第一行log到Can_Write函数后的log打印,计算时间差,再加10ms左右
ret = Can_Write(hth, &PduInfo);
printf("%s() Result: %d, hth=%d\n", __func__, ret, hth);
7.2通过示波器计算
这里顺便讲下safety域GPIO的控制,调用非常简单
#include "hal_dio.h"
extern const domain_res_t g_gpio_res;
void time_test(void){
bool ret = true;
static void *g_handle;
ret = hal_dio_creat_handle(&g_handle,g_gpio_res.res_id[0]);
if (ret) {
hal_dio_write_channel(g_handle, 19, 1); // GPIO_E7;
}
else {
hal_dio_release_handle(&g_handle);
}
}
上面的代码是我摘出来的,可以直接插入can demo的代码中使用
详细关于每个域GPIO如何调用请参考《Semidrive_IO及Pinctrl使用指南.pdf》,下面对两个函数的参数有详细讲解
创建 Pinctrl 句柄
bool hal_port_creat_handle(void **handle, uint32_t port_res_glb_idx)
➢ handle: Pinctrl 句柄
➢ port_res_glb_idx: pin 对应的资源 ID safety域用的controller GPIO1
写数据到 GPIO
void hal_dio_write_channel(void *handle, const Dio_ChannelType ChannelId,
const Dio_LevelType Level)
➢ handle: GPIO controller 句柄
➢ ChannelId: GPIO 所在的通道 ID 对应SDConfigTool中index
➢ Level: 数据的内容,GPIO 高/低
在CANFD的demo中在Can_Write函数后,添加time_test函数实现GPIO_E7置高
通过示波器双通道,选择GPIO_E7上升沿触发,计算12v上电到GPIO_E7置高之间的时间差值就可以计算出来上电到第一帧看数据发出的时间
8.如何使用CAN
1.can_cfg.c 中修改enableCANFD = false
2.修改CAN demo中数据包的长度 length = 8U;