当前位置: 首页 > news >正文

CCP协议代码实现—代码结构

文章目录

  • 前言
  • 一、CCP的代码结构
  • 二、CCP的代码集成
  • 总结

前言

大家好,我是左工,经过多天的努力,我们终于完成了CCP的基本操作和基本命令学习。从本篇开始我们将学习CCP协议的代码实现。再次强调一点基本命令的学习虽然枯燥,但这是CCP协议实现的基础,希望大家能反复揣摩直到完全理解。


一、CCP的代码结构

CCP协议栈的代码比较简单,只有六个文件如下所示。

这六个文件的作用分别如下所示:

文件解释
ccp_core.c协议栈核心实现
ccp_core.h协议栈核心实现头文件
ccp_daq.cDAQ管理实现
ccp_types.h数据类型定义
ccp_interface_tc.c芯片平台适配接口
ccp_interface_tc.h芯片平台适配接口头文件

其中前四个文件是不需要修改的,只需要根据芯片平台将“ccp_interface_tc.c”这个文件中给出的提示将相关函数给补齐就行了。如下所示就是ccp_interface_tc.c文件中关于函数tc_ccp_can_send()的描述。

/** * @brief CCP的CAN报文发送接口 * @param handle CCP句柄 * @param buffer 数据缓冲区 * @param length 数据长度 * @param odt_index odt索引 * @return 错误码 * * 用户需要在此函数中实现CAN消息发送: * - 配置发送消息对象 * - 填充CAN数据 * - 启动消息发送 */uint8_ttc_ccp_can_send(ccp_handle_t*handle,uint8_t*buffer,uint8_tlength,uint8_todt_index){/* TODO: 用户需要实现CAN消息发送 *//* 示例实现: * 1. 选择合适的发送消息对象 * 2. 配置消息对象的CAN ID和数据长度 * 3. 将数据复制到消息对象的数据寄存器 * 4. 设置发送请求位 * 5. 等待发送完成或检查发送状态 */returnCCP_OK;}

ccp_interface_tc.c文件中需要补充的函数也不多,只有如下8个函数。每一函数都有详细的解释和定义。左工后续也会教大家如何编写接口文件。

/* CCP的CAN报文发送接口*/uint8_ttc_ccp_can_send(ccp_handle_t*handle,uint8_t*buffer,uint8_tlength,uint8_todt_index);uint8_ttc_ccp_can_tx_callback(ccp_handle_t*handle);/* 内存读写接口 */uint8_ttc_memory_read(uint32_taddress,uint8_t*data,uint32_tsize);uint8_ttc_memory_write(uint32_taddress,uint8_t*data,uint32_tsize);/* 标定页管理 */uint8_ttc_cal_page_init(void);uint8_ttc_cal_page_switch(uint32_tpage_address);uint32_ttc_cal_page_get_active(void);/* 定时器 */uint32_ttc_timer_get_tick(void);

对于其他文件的代码,大家不用担心,也有详细的注释说明,如下为ccp_core.c文件中的部分代码,大家可以根据注释非常清楚的读懂代码。

/* CCP协议栈处理 */uint8_tccp_process(ccp_handle_t*handle,uint8_t*data,uint8_tlength){ccp_packet_tpacket;ccp_response_tresponse;uint8_tresult;if(!handle||!data||length<8){returnCCP_ERR_INVALID_PARAM;}/* 解析数据包 */packet.command=data[0];packet.counter=data[1];memcpy(packet.data,&data[2],sizeof(packet.data));/* 处理命令 */result=ccp_process_command(handle,&packet,&response);

各位可以私信左工,后台发送“1”即可获取上述协议栈代码。

二、CCP的代码集成

我们已经有了协议栈代码了,那么如何集成呢?首先请大家回顾前面的文章搭建英飞凌Aurix系列TC334芯片开源免费开发工具链,将开发环境搭建起来。然后按照文章中的方法,创建一个工程。并找到工程所在文件夹将下载的协议栈代码文件直接复制到工程的跟目录下面即可。

然后在AurixDev编译环境中右键单击工程名,再点击“Refresh”即完成了协议栈代码的集成。

协议栈代码的调用主要在Cup0_Main.c这个文件中进行,首先是引入头文件。

#include"drive_tc.h"//底层驱动#include"ccp_core.h"//CCP实现

其中“drive_tc.h”文件主要作用是驱动CAN模块和GTP定时器模块,大家可以参考文章Aurix英飞凌TC334芯片CAN模块配置和Aurix英飞凌TC334芯片GPT模块定时器配置完成底层驱动的编写。后续左工也会单独讲解如何编写驱动文件。

然后就是建立CCP模块相关的变量。

/* 全局CCP句柄 */ccp_handle_tg_ccp_handle;/* 设备信息 */staticccp_device_info_tg_device_info={.version_major=CCP_VERSION_MAJOR,.version_minor=CCP_VERSION_MINOR,.resource_availability=CCP_PROTECT_CAL|CCP_PROTECT_DAQ|CCP_PROTECT_PGM,.protection_status=CCP_PROTECT_CAL|CCP_PROTECT_DAQ|CCP_PROTECT_PGM,.device_name="TC_CCP_DEMO"};

观测量和标定量的定义也被放在了这个文件中了。

/*观测量定义*/#pragmasection all"app.meas_var"volatileuint32 Meas_SysCount=0ul;//观测量volatileuint32 Meas_Output=0ul;//观测量#pragmasection all restore/*标定量定义*/#pragmasection all"app.cali_var"constvolatileuint32 Cali_Proportion=0ul;//标定参数1constvolatileuint32 Cali_Offset=0ul;//标定参数2#pragmasection all restore

这四个变量是不是很眼熟,没错就是文章CCP基本操作流程与效果展示使用的四个变量。我们这里再把这四个变量的用法重复一遍:

  1. 名为“Meas_SysCount”的变量,这个变量每隔0.5秒,自增1,增长到20的时候,就会重新归零。
  2. 名为“Meas_Output”的变量,这个变量的值为:
    Meas_Output = Cali_Proportion * 16 + Cali_Offset。

其中两个变量有前缀“Meas”这是测量量(Measure)的的简写。两外两个变量的前缀是”Cali“这是标定量(Calibration)的简写。

再下一步就是要在core0_main()函数中完成初始化和局部变量定义。

GPTimer_init();CAN_init();ccp_init(&g_ccp_handle,&g_device_info);//初始化ccpuint8 buf[8]={0};uint8 len=0;

最后就是在while(1)循环中完成CCP指令的周期性处理即可。

while(1){/*CCP接收处理*/if((rx_flag==1)&&(rx_id==0x010)){rx_flag=0;/*清除接收标志*/len=rx_len;/*从通用接收缓冲区复制消息到ccp处理缓冲区*/for(uint32 cnt=0;(cnt<len)&&(cnt<8);cnt++){buf[cnt]=rx_buf[cnt];}ccp_process(&g_ccp_handle,buf,len);/*处理CCP命令*/}/*时基处理,1ms未到达则跳过后续代码*/if(TimeOut_1ms_Flag==0){continue;}TimeOut_1ms_Flag=0;TimeCount_1ms+=1;ccp_daq_timer_handler(&g_ccp_handle);/*CCP_DAQ处理,1ms触发一次*//*App定时任务*/if(TimeCount_1ms%500==0)//500ms{Meas_SysCount+=1;//每0.5秒自增1Meas_Output=Cali_Proportion*16+Cali_Offset;//CCP标定与观测演示}/*每10s重置时基*/if(TimeCount_1ms>=10000)//10s{TimeCount_1ms=0;}}

我们可以看出来在上面的调用逻辑下,CCP指令的处理是发生在收到CAN报文触发中断之后,而DAQ相关指令的处理是1ms处理一次。

现在我们所有的集成工作已经结束了,Cup0_Main.c文件的所有代码如下所示。完成这些工作,应该是能顺利完成编译了。

#include"drive_tc.h"//底层驱动#include"ccp_core.h"//CCP实现IFX_ALIGN(4)IfxCpu_syncEvent g_cpuSyncEvent=0;/************************CCP模块相关变量************************//* 全局CCP句柄 */ccp_handle_tg_ccp_handle;/* 设备信息 */staticccp_device_info_tg_device_info={.version_major=CCP_VERSION_MAJOR,.version_minor=CCP_VERSION_MINOR,.resource_availability=CCP_PROTECT_CAL|CCP_PROTECT_DAQ|CCP_PROTECT_PGM,.protection_status=CCP_PROTECT_CAL|CCP_PROTECT_DAQ|CCP_PROTECT_PGM,.device_name="TC_CCP_DEMO"};/*观测量定义*/#pragmasection all"app.meas_var"volatileuint32 Meas_SysCount=0ul;//观测量,每0.5秒自增1volatileuint32 Meas_Output=0ul;//观测量,公式:Meas_Output = Cali_Proportion * 16 + Cali_Offset#pragmasection all restore/*标定量定义*/#pragmasection all"app.cali_var"constvolatileuint32 Cali_Proportion=0ul;//标定参数1constvolatileuint32 Cali_Offset=0ul;//标定参数2#pragmasection all restore/************************主函数************************/voidcore0_main(void){IfxCpu_enableInterrupts();/* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!! * Enable the watchdogs and service them periodically if it is required */IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());/* Wait for CPU sync event */IfxCpu_emitEvent(&g_cpuSyncEvent);IfxCpu_waitEvent(&g_cpuSyncEvent,1);GPTimer_init();CAN_init();ccp_init(&g_ccp_handle,&g_device_info);//初始化ccpuint8 buf[8]={0};uint8 len=0;while(1){/*CCP接收处理*/if((rx_flag==1)&&(rx_id==0x010)){rx_flag=0;/*清除接收标志*/len=rx_len;/*从通用接收缓冲区复制消息到ccp处理缓冲区*/for(uint32 cnt=0;(cnt<len)&&(cnt<8);cnt++){buf[cnt]=rx_buf[cnt];}ccp_process(&g_ccp_handle,buf,len);/*处理CCP命令*/}/*时基处理,1ms未到达则跳过后续代码*/if(TimeOut_1ms_Flag==0){continue;}TimeOut_1ms_Flag=0;TimeCount_1ms+=1;ccp_daq_timer_handler(&g_ccp_handle);/*CCP_DAQ处理,1ms触发一次*//*App定时任务*/if(TimeCount_1ms%500==0)//500ms{Meas_SysCount+=1;//每0.5秒自增1Meas_Output=Cali_Proportion*16+Cali_Offset;//CCP标定与观测演示}/*每10s重置时基*/if(TimeCount_1ms>=10000)//10s{TimeCount_1ms=0;}}}

总结

今天我们讲解了CCP协议栈代码结构和集成方法。在今天的描述中我们粗略的引入了如何定义观测量和标定量。我们用到了如下几行代码,这几行代码是什么意思呢,关键字“#pragma”是如何将这四个变量定义在指定的地址上的,如何与.lsl文件进行互动的?下一次左工将回答这些问题。

/*观测量定义*/#pragmasection all"app.meas_var"volatileuint32 Meas_SysCount=0ul;//观测量volatileuint32 Meas_Output=0ul;//观测量#pragmasection all restore/*标定量定义*/#pragmasection all"app.cali_var"constvolatileuint32 Cali_Proportion=0ul;//标定参数1constvolatileuint32 Cali_Offset=0ul;//标定参数2#pragmasection all restore

再次提醒各位可以私信左工,后台发送“1”即可获取上述协议栈代码。请敬请收藏关注,不迷路。

http://www.jsqmd.com/news/541615/

相关文章:

  • 大模型安全:小白也能懂的Agent开发防御秘籍(收藏学习)
  • ESPNexUpload库详解:ESP32/8266烧录Nextion TFT固件实战
  • RPA选型指南:不同行业场景下,企业该如何选择最合适的厂商?
  • 基于FDM - EDFM的油气藏地层压力场计算:MATLAB实战
  • OpenClaw低资源运行方案:Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF在轻量设备上的优化
  • 用过才敢说!AI论文平台深度测评与推荐
  • 形转化理论七本性计算模拟项目:从第一性原理生成物理世界的可计算探索
  • BetaFlight黑匣子浏览器:5个神奇功能让你轻松读懂无人机的“飞行日记“✨
  • RPA在财务中的应用:对账、报销、报表自动化全解析
  • 告别重复造轮子:用快马平台将Coze工作流高效转化为可部署应用
  • ARM A73嵌入式设备从RAMDisk切换Ubuntu根文件系统实施方案
  • 小白学电子电路电源篇
  • 终极指南:如何在浏览器中一键解锁加密音乐文件,实现跨平台播放自由
  • 微信小程序+MySQL实战:手把手教你搭建传染病防控系统(附源码)
  • 图文并茂手把手教你Claude Code 多智能体 Agent Teams,一人变团队
  • Ntopng权限绕过漏洞(CVE-2021-28073)深度分析与实战复现
  • OpenClaw跨文档处理:nanobot合并多个Excel生成汇总报告
  • 2026Y5-48锅炉风机优质产品推荐榜密封性能出色 - 优质品牌商家
  • 代码随想录算法训练营第七天|454、两数相加II 383、赎金信 15、三数之和 18、四数之和
  • Linux Ubuntu 24.04 Server 超简单部署 Fast GPT(新手零踩坑)
  • OpenClaw多模态扩展:nanobot镜像处理图片与文本混合任务
  • Rocky Linux 9.5离线环境保姆级教程:手把手搞定Docker 25.0.5完整部署
  • 循环队列在嵌入式消息处理中的实现与应用
  • 4重防护构建安卓安全屏障:APKMirror应用管理全攻略
  • 《PyCharm 自定义背景图最简易教程,让你的编辑器颜值拉满!》
  • 2026论文写作工具红黑榜:AI论文平台怎么选?清单来了
  • CTFSHOW web入门 爆破 web23
  • 为什么3分钟搞懂AI
  • 【2026最新】IDEA 2025.3最新安装教程
  • 使命召唤系列合集COD 1-21部 中文版 全DLC+MOD修改器 PC单机联机游戏射击游戏