CCP协议代码实现—源码获取
大家好,我是左工,经过多天的努力,我们终于完成了CCP的基本操作和基本命令学习。从本篇开始我们将学习CCP协议的代码实现。再次强调一点基本命令的学习虽然枯燥,但这是CCP协议实现的基础,希望大家能反复揣摩直到完全理解。对于本文需要的协议栈,可以关注公众号,加左工微信,给左工发送“CCP源码”即可获取上述协议栈代码。
CCP的代码结构

|
ccp_core.c |
协议栈核心实现 |
|
ccp_core.h |
协议栈核心实现头文件 |
|
ccp_daq.c |
DAQ管理实现 |
|
|
数据类型定义 |
|
ccp_interface_tc.c |
芯片平台适配接口 |
|
|
|
/*** @brief CCP的CAN报文发送接口* @param handle CCP句柄* @param buffer 数据缓冲区* @param length 数据长度* @param odt_index odt索引* @return 错误码** 用户需要在此函数中实现CAN消息发送:* - 配置发送消息对象* - 填充CAN数据* - 启动消息发送*/uint8_t tc_ccp_can_send(ccp_handle_t *handle, uint8_t *buffer, uint8_t length, uint8_t odt_index){/* TODO: 用户需要实现CAN消息发送 *//* 示例实现:* 1. 选择合适的发送消息对象* 2. 配置消息对象的CAN ID和数据长度* 3. 将数据复制到消息对象的数据寄存器* 4. 设置发送请求位* 5. 等待发送完成或检查发送状态*/return CCP_OK;}
/* CCP的CAN报文发送接口*/uint8_ttc_ccp_can_send(ccp_handle_t *handle, uint8_t *buffer, uint8_t length, uint8_t odt_index);uint8_ttc_ccp_can_tx_callback(ccp_handle_t *handle);/* 内存读写接口 */uint8_ttc_memory_read(uint32_t address, uint8_t *data, uint32_t size);uint8_ttc_memory_write(uint32_t address, uint8_t *data, uint32_t size);/* 标定页管理 */uint8_ttc_cal_page_init(void);uint8_ttc_cal_page_switch(uint32_t page_address);uint32_ttc_cal_page_get_active(void);/* 定时器 */uint32_ttc_timer_get_tick(void);
/* CCP协议栈处理 */uint8_tccp_process(ccp_handle_t *handle, uint8_t *data, uint8_t length){ccp_packet_t packet;ccp_response_t response;uint8_t result;if (!handle || !data || length < 8) {return CCP_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);


#include"drive_tc.h"//底层驱动#include"ccp_core.h"//CCP实现
/* 全局CCP句柄 */ccp_handle_t g_ccp_handle;/* 设备信息 */static ccp_device_info_t g_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"};
/*观测量定义*/#pragma section "app.meas_var"volatile uint32 Meas_SysCount = 0ul; //观测量volatile uint32 Meas_Output = 0ul; //观测量#pragma section/*标定量定义*/#pragma section "app.cali_var"const volatile uint32 Cali_Proportion = 0ul; //标定参数1const volatile uint32 Cali_Offset = 0ul; //标定参数2#pragma section
-
名为“Meas_SysCount”的变量,这个变量每隔0.5秒,自增1,增长到20的时候,就会重新归零。 -
名为“Meas_Output”的变量,这个变量的值为:
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;}}
#include"drive_tc.h"//底层驱动#include"ccp_core.h"//CCP实现IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;/************************CCP模块相关变量************************//* 全局CCP句柄 */ccp_handle_t g_ccp_handle;/* 设备信息 */static ccp_device_info_t g_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"};/*观测量定义*/#pragma section "app.meas_var"volatile uint32 Meas_SysCount = 0ul; //观测量,每0.5秒自增1volatile uint32 Meas_Output = 0ul; //观测量,公式:Meas_Output = Cali_Proportion * 16 + Cali_Offset#pragma section/*标定量定义*/#pragma section "app.cali_var"const volatile uint32 Cali_Proportion = 0ul; //标定参数1const volatile uint32 Cali_Offset = 0ul; //标定参数2#pragma section/************************主函数************************/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文件进行互动的?下一次左工将回答这些问题。
/*观测量定义*/#pragma section "app.meas_var"volatile uint32 Meas_SysCount = 0ul; //观测量volatile uint32 Meas_Output = 0ul; //观测量#pragma section/*标定量定义*/#pragma section "app.cali_var"const volatile uint32 Cali_Proportion = 0ul; //标定参数1const volatile uint32 Cali_Offset = 0ul; //标定参数2#pragma section

夜雨聆风