/****************************************************************************** 版权所有: 文件名称: mb.c 文件名称: mb.c 文件版本: 01.01 创建作者: sunxi 创建日期: 2022-05-17 功能说明: 邮箱驱动 其它说明: 修改记录: */ #include "bspconfig.h" #include "bsp.h" #include "mb.h" #include #include #include #include #include #include #include #include #include #include #define CO_IOCTL_GET_REG 1 #define CO_IOCTL_SET_REG 2 #define CO_IOCTL_EXECUTE 3 #define CO_IOCTL_GET_DATA 4 #define CO_IOCTL_SET_DATA 5 #define CO_IOCTL_GET_CONFIGS 6 #define CO_IOCTL_SET_PC 7 #ifndef CO_MB_FIFO_SIZE #define CO_MB_FIFO_SIZE 32//经测试,只能这么大的buf #endif struct co_io { uint8_t meta; uint16_t metadata; uint32_t data[CO_MB_FIFO_SIZE - 1]; uint8_t len; }; struct mb_co { char *name; pthread_t thread_id; int fd_co; struct co_io coio; }; static struct mb_co *pmb; static inline void dmsg_u8(uint8_t *data, int length, char *str) { int i, j; int tmp; printf("%s:\n", str); for (i = 0; i < (length / 16); i++) { for (j = 0; j < 16; j++) printf("%02x ", data[i * 16 + j]); printf("\n"); } tmp = (length / 16) * 16; for (i = 0; i < (length % 16); i++) printf("%02x ", data[tmp + i]); if (length % 16) printf("\n"); } /****************************************************************************** 函数名称: mb_write 函数版本: 01.01 创建作者: sunxi 创建日期: 2022-05-17 函数说明: 向邮箱写入数据. 参数说明: cmd:命令号 data:写入数据 len:写入数据长度,注意: 如果转入2个uint32_t的数据,那么长度为2,不是8. 返回值: 成功返回0, 失败返回-1 修改记录: !!!!!!!!! 注意: 如果转入2个uint32_t的数据,那么长度为2,不是8. */ int mb_write(uint16_t cmd, uint32_t *data, uint8_t len) { return 0;//noted by ygl: 邮箱功能暂时不实现 int i; int ret; struct mb_co *co = NULL; if(pmb == NULL) return -1; if(data == NULL) return -1; if(len > (CO_MB_FIFO_SIZE - 1)) return -1; co = pmb; for (i = 0; i < len; i++) co->coio.data[i] = data[i]; /* meta =0时,metadata无效,对方收不到metadata值。 meta =为非0时,metadata置数,对方也收到metadata值。 */ /* ipc message parameters */ co->coio.meta = 1;//noted by sunxi: 与裸核,约定为1 co->coio.metadata = cmd; co->coio.len = len; #if 0 for (i = 0; i < co->coio.len; i++) printf("%04X ", co->coio.data[i]); printf("\r\n"); #endif ret = ioctl(co->fd_co, CO_IOCTL_SET_DATA, &co->coio); if (ret) printf("send to %s failed, ret = %d\n",co->name, ret); return 0; } /****************************************************************************** 函数名称: mb_notice_time_update 函数版本: 01.01 创建作者: sunxi 创建日期: 2022-05-17 函数说明: 用邮箱告知时间更新了 参数说明: 返回值: 成功返回0, 失败返回-1 修改记录: */ int mb_notice_time_update(void) { int ret; uint32_t data[31]; data[0] = MB_CMD_TIME; data[1] = MB_CMD_TIME; ret = mb_write(MB_CMD_TIME, data, 2); if(ret<0) printf("mb_write fail!!! ret= %d\n", ret); return ret; } /****************************************************************************** 函数名称: mb_notice_freqTr_update 函数版本: 01.01 创建作者: sunxi 创建日期: 2022-05-17 函数说明: 用邮箱告知频率跟踪更新了 参数说明: 返回值: 成功返回0, 失败返回-1 修改记录: */ int mb_notice_freqTr_update(void) { int ret; uint32_t data[31]; data[0] = MB_CMD_FREQTR; data[1] = MB_CMD_FREQTR; ret = mb_write(MB_CMD_FREQTR, data, 2); if(ret<0) printf("mb_write fail!!! ret= %d\n", ret); return ret; } /****************************************************************************** 函数名称: mb_notice_RfV_update 函数版本: 01.01 创建作者: sunxi 创建日期: 2022-05-17 函数说明: 用邮箱告知AD7616参考电压范围更新了 参数说明: no:第n片7616 返回值: 成功返回0, 失败返回-1 修改记录: */ int mb_notice_RfV_update(uint8_t no) { int ret; uint32_t data[31]; data[0] = no; data[1] = no; ret = mb_write(MB_CMD_RfV, data, 2); if(ret<0) printf("mb_write fail!!! ret= %d\n", ret); return ret; } static int co_mb_open(struct mb_co *co, char *name) { int fd_co; printf("open co mb dev %s\n", name); fd_co = open(name, O_RDWR); if (!fd_co) { printf("open co dev failed\n"); return -1; } co->name = name; co->fd_co = fd_co; return 0; } static void *thread_co_test(void *arg) { struct mb_co *co = pmb; //int i; int ret; while (1) { sleep(1); #if 0 crc++; for (i = 0; i < (CO_MB_FIFO_SIZE - 1); i++) data[i] = i+crc; ret = mb_write(MB_CMD_TIME, data, 31); if(ret<0) printf("send to %s failed, ret = %d\n",co->name, ret); #endif ret = mb_notice_time_update(); if(ret<0) printf("send to %s failed, ret = %d\n",co->name, ret); } printf("thread co exit\r\n"); pthread_exit(NULL); } //测试代码 void mb_test(void) { int ret; if((ret = pthread_create(&pmb->thread_id, NULL, thread_co_test, pmb)) == 0) printf("thread co0 create success\r\n"); else printf("thread co0 create fail ret=%d\r\n", ret); } /****************************************************************************** 函数名称: mb_init 函数版本: 01.01 创建作者: sunxi 创建日期: 2022-05-17 函数说明: mb初始化. 参数说明: 无 返回值: 成功返回0, 失败返回-1 修改记录: */ int mb_init(void) { // int ret; pmb = malloc(sizeof(struct mb_co)); memset(pmb, 0, sizeof(struct mb_co)); if(co_mb_open(pmb, "/dev/arv-shmem")) { printf("open mb error\r\n"); return -1; } //mb_test();//sunxi for test return 0; } /****************************************************************************** 函数名称: mb_exit 函数版本: 01.01 创建作者: sunxi 创建日期: 2022-05-17 函数说明: mb反初始化. 参数说明: 无 返回值: 总是返回0. 修改记录: */ int mb_exit(void) { if(pmb) { if(pmb->fd_co) close(pmb->fd_co); } return 0; }