/****************************************************************************** 版权所有: @copyright (C) 2024-2034 HaiYang Technology Corp. All rights reserved. 文件名称: shm_comm_packet.c 文件版本: 01.01 创建作者: zhaoyang 创建日期: 2025-08-25 功能说明: 共享内存通信打包 其它说明: 修改记录: */ /*------------------------------- 头文件 -------------------------------------- */ #include "bsp_shm.h" #include #include #include /*------------------------------- 宏定义 -------------------------------------- */ /*------------------------------ 类型结构 ------------------------------------- */ //CRC-16 表 const unsigned short UserLookup[256]= { 0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241, 0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440, 0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40, 0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841, 0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40, 0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41, 0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641, 0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040, 0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240, 0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441, 0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41, 0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840, 0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41, 0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40, 0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640, 0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041, 0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240, 0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441, 0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41, 0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840, 0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41, 0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40, 0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640, 0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041, 0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241, 0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440, 0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40, 0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841, 0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40, 0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41, 0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641, 0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040 }; /*------------------------------ 函数声明 ------------------------------------- */ /*------------------------------ 外部函数 ------------------------------------- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性. */ /************************************************************************** 函数名称:CrcStr 函数版本:1.00 作者: 创建日期:2005.4.13 函数功能说明:计算1个字节数组的CRC-16 输入参数: p =数组的开始地址 len =数组长度 返回值: crc =计算后的CRC-16结果 更新信息: 更新日志1: 日期: 修改者: 修改内容: 修改原因: ***************************************************************************/ static unsigned short CrcStr(unsigned char *p,int len) { unsigned short crc=0; bool bZero=true; while(len-->0) { if(*p!=0)bZero=false; crc=UserLookup[(crc&0xff)^(*p++)]^(crc>>8); } if(bZero)crc=0x5678; //若全为0,crc返回就不要为零 return crc; } /****************************************************************************** 函数名称: shm_comm_packet_write 函数版本: 01.01 创建作者: zhaoyang 创建日期: 2025-08-25 函数说明: 向共享内存写入数据(自动处理A,B,crc). 参数说明: addr:共享内存的地址 data:写入数据 len:写入数据长度 返回值: 成功返回写入数据的长度, 失败返回-1 修改记录: 使用说明: 输入参数data为带有A,B和crc的结构体,len为整个结构体的长度 应用层不需要理会A,B和crc. */ int shm_comm_packet_write(uint32_t addr, uint8_t *data, uint32_t len) { uint16_t A; int ret; uint16_t crc = 0; if(data == NULL) return -1; if(len == 0 ) return -1; //A++ memcpy(&A,&SHM_BASE_W[addr],2); A++; memcpy(&SHM_BASE_W[addr],&A,2); //写数据区 ret = shm_write(addr+4, data+4, len-6); if(ret == -1) return -1; //crc crc = CrcStr(data+4, len-6);//CRC memcpy(&SHM_BASE_W[addr+len-2],&crc,2); //B++ memcpy(&SHM_BASE_W[addr+2],&A,2); //A和B保证一样 return ret+6;//加上A,B,crc的长度 } /****************************************************************************** 函数名称: shm_comm_packet_read 函数版本: 01.01 创建作者: zhaoyang 创建日期: 2025-08-25 函数说明: 读取共享内存的数据(自动处理A,B,crc). 参数说明: addr:所以读取共享内存的地址 len:需要读取数据的长度 out_data:输出buf out_data_size:输出buf的长度 返回值: 成功返回读取数据的长度, 失败返回 <0 修改记录: 使用说明: 输入参数out_data为带有A,B和crc的结构体,len为整个结构体的长度 应用层不需要理会A,B和crc. */ int shm_comm_packet_read(uint32_t addr, uint32_t len, uint8_t *out_data, uint32_t out_data_size) { uint16_t A,B; //uint16_t last_A = 0; //uint16_t last_B = 0; int ret; uint16_t crc = 0; uint16_t read_crc = 0; //shm_read(addr, 2, (uint8_t*)&last_A, sizeof(last_A)); //shm_read(addr+2, 2, (uint8_t*)&last_B, sizeof(last_B)); //printf("last_A=%X, last_B=%X\n", last_A,last_B); //if(last_A == last_B) { //idle ret = shm_read(addr, len, out_data, out_data_size); A = out_data[0]+((uint16_t)out_data[1]<<8); B = out_data[2]+((uint16_t)out_data[3]<<8); //printf("A=%X, B=%X\n", A,B); if((A == B) )//&& (A == last_A)) { //在拷贝过程中,数据没有被修改 crc = CrcStr(out_data+4,len-6); read_crc = out_data[len-2]+((uint16_t)out_data[len-1]<<8); //printf("cal crc=%04X, read crc=%04X\n", crc,read_crc); if(crc != read_crc) { //crc error return -3; } } else { //busy 裸核正在写数据 return -2; } } //else //{ //busy 裸核正在写数据 // return -2; //} return ret; } /****************************************************************************** 函数名称: shm_comm_packet_read_noABcrc 函数版本: 01.01 创建作者: zhaoyang 创建日期: 2025-08-25 函数说明: 读取共享内存的数据(结构体不存在A,B,crc). 参数说明: addr:所以读取共享内存的地址 len:需要读取数据的长度 out_data:输出buf out_data_size:输出buf的长度 返回值: 成功返回读取数据的长度, 失败返回 <0 修改记录: 使用说明: 如:Ad7616采样点结构 本函数只处理不含有A,B和crc的结构体 */ int shm_comm_packet_read_noABcrc(uint32_t addr, uint32_t len, uint8_t *out_data, uint32_t out_data_size) { int ret; ret = shm_read(addr, len, out_data, out_data_size); return ret; } /*------------------------------ 测试函数 ------------------------------------- */ typedef struct testtt_t { uint16_t A; uint16_t B; uint16_t rc[16]; uint16_t crc; }testtt_t; testtt_t aabfd,readaaaa; void shm_comm_test(void) { int i; int ret = 0; for(i=0;i<16;i++) { aabfd.rc[i]=i+2; printf("aabfd.rc[%d]=%X\n",i,aabfd.rc[i]); } ret = shm_comm_packet_write(0,(uint8_t*)&aabfd,sizeof(aabfd)); printf("shm_comm_packet_write ret=%d\n",ret); if(ret > 0) { for(i=0;i 0) { for(i=0;i<16;i++) { printf("%X ",readaaaa.rc[i]); } printf("\n "); } } /*------------------------------ 文件结束 ------------------------------------- */