/** * @file ModuleConfig.c * @brief 从FLASH中读取配置信息;解析蓝牙请求,将配置信息写入到FLASH中 * @author Huo Yujia (huoyujia081@126.com) * @version 1.0 * @date 2024-08-19 * @note 目前的配置信息仅包含4G、以太网、RS485三个模块的内容 */ #include #include #include #include #include #include #include #include __attribute__((aligned(4))) module_cfg defaultConfiguration = {.moduleName = "XiZi", .type = NET_MODULE_TYPE_TCP_C_DHCP, .destinationIpAddress_4G = {115, 238, 53, 59}, .destinationPort_4G[0] = 10208 % 256, .destinationPort_4G[1] = 10208 / 256, .mqttSwitch_4G = 0, .mqttTopic_4G = "/SubTopic1", .mqttUsername_4G = "username", .mqttPassword_4G = "password", .mqttClientId_4G = "clientId", .destinationIpAddress_Ethernet = {115, 238, 53, 59}, .destinationPort_Ethernet[0] = 10208 % 256, .destinationPort_Ethernet[1] = 10208 / 256, .dhcpSwitch_Ethernet = 1, .sourceIpAddress_Ethernet = {192, 168, 137, 10}, .sourcePort_Ethernet[0] = 1000 % 256, .sourcePort_Ethernet[1] = 1000 / 256, .sourceSubnetMask_Ethernet = {255, 255, 255, 0}, .sourceGateway_Ethernet = {192, 168, 137, 1}, .baudRate_Rs485 = 3, .dataBits_Rs485 = 1, .stopBits_Rs485 = 1, .parity_Rs485 = 1, .cfgFlag[0] = checkcode1, .cfgFlag[1] = checkcode2}; // 默认配置信息 u8 Configbuf[MODULE_CFG_LEN]; // 从flash中读取的配置信息数组 pmodule_cfg CFG = (pmodule_cfg)Configbuf; // 从flash中读取的配置信息指针 pthread_mutex_t romConfigurationMutex; // CFG的互斥锁 /** * @brief 擦除FLASH块,最小的块为256B * @param Page_Address 擦除页的开始地址 * @param Length 擦除数据长度 */ void CFG_ERASE(uint32_t Page_Address, u32 Length) { u32 NbrOfPage, EraseCounter; FLASH_Unlock_Fast(); NbrOfPage = Length / FLASH_PAGE_SIZE; for (EraseCounter = 0; EraseCounter < NbrOfPage; EraseCounter++) { FLASH_ErasePage_Fast(Page_Address + (FLASH_PAGE_SIZE * EraseCounter)); } FLASH_Lock_Fast(); } /** * @brief 写FLASH数据块 * @param StartAddr 写入页的开始地址 * @param Buffer 写入的数据缓冲区 * @param Length 写入的数据长度 * @return FLASH_Status FLASH状态,定义位置:Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Peripheral/inc/ch32v20x_flash.h */ FLASH_Status CFG_WRITE(u32 StartAddr, u8 *Buffer, u32 Length) { u32 address = StartAddr; u32 *p_buff = (u32 *)Buffer; FLASH_Status FLASHStatus = FLASH_COMPLETE; FLASH_Unlock(); while ((address < (StartAddr + Length)) && (FLASHStatus == FLASH_COMPLETE)) { FLASHStatus = FLASH_ProgramWord(address, *p_buff); address += 4; p_buff++; } FLASH_Lock(); return FLASHStatus; } /** * @brief 从FLASH中读取数据块 * @param StartAddr 读取页的开始地址 * @param Buffer 读取的数据缓冲区 * @param Length 读取的数据长度 */ void CFG_READ(u32 StartAddr, u8 *Buffer, u32 Length) { u32 address = StartAddr; u32 *p_buff = (u32 *)Buffer; while (address < (StartAddr + Length)) { *p_buff = (*(u32 *)address); address += 4; p_buff++; } } /** * @brief 尝试使用配置通过4G连接到服务器,并且蓝牙响应连接状态报文。 * @param requestId 蓝牙请求报文ID * @note 在解析完成蓝牙请求和写入FLASH配置之后调用该函数 */ void connectServer_4G(uint8_t requestId) { uint8_t destinationIpAddress[16] = {}; // 字符串形式的目的IP地址 uint8_t destinationPort[6] = {}; // 字符串形式的目的端口号 struct Adapter *adapter = AdapterDeviceFindByName(ADAPTER_4G_NAME); // 查找以太网模块适配器 /* 如果4G模块仍未初始化,则返回连接失败报文 */ if (adapter->agent == NULL) { uint8_t notificationReport[4]; notificationReport[0] = requestId; notificationReport[1] = 0x02; notificationReport[2] = 0x01; notificationReport[3] = 0x02; bStatus_t res; while ((res = peripheralNotify(notificationReport, sizeof(notificationReport))) != SUCCESS) { if (res != blePending) { // 发送失败的原因不是阻塞,放弃继续发送 printf("peripheralNotify failed, res: 0x%02x\n", res); break; } else { // 发送失败的原因是阻塞,则等待10ms后再次发送 PrivTaskDelay(10); } } return; } /* 获取互斥锁 */ PrivMutexObtain(&adapter->lock); // 若其他线程正在使用adapter,则阻塞等待 PrivMutexObtain(&romConfigurationMutex); // 若其他线程正在读取或者写入CFG,则阻塞等待 /* 尝试连接到服务器 */ sprintf(destinationIpAddress, "%u.%u.%u.%u", CFG->destinationIpAddress_4G[0], CFG->destinationIpAddress_Ethernet[1], CFG->destinationIpAddress_4G[2], CFG->destinationIpAddress_4G[3]); sprintf(destinationPort, "%hu", (unsigned short)CFG->destinationPort_4G[0] | CFG->destinationPort_4G[1] << 8); printf("-*-*-*-*-AdapterDeviceConnect*-*-*-*-\n"); printf("destinationIpAddress: %s\n", destinationIpAddress); printf("destinationPort: %s\n", destinationPort); printf("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*--*-*-*\n"); if (CFG->mqttSwitch_4G == 1) { // 如果使能MQTT AdapterDeviceMqttConnect(adapter, destinationIpAddress, destinationPort, CFG->mqttClientId_4G, CFG->mqttUsername_4G, CFG->mqttPassword_4G); } else { // 如果禁用MQTT AdapterDeviceConnect(adapter, CLIENT, destinationIpAddress, destinationPort, IPV4); } /* 蓝牙反馈连接状态 */ AdapterDeviceNetstat(adapter); // 读取网络状态 if (CFG->mqttSwitch_4G == 0 && adapter->network_info.is_connected || CFG->mqttSwitch_4G == 1 && adapter->network_info.mqttIsConnected) { // 如果连接成功 /* 释放互斥锁 */ PrivMutexAbandon(&romConfigurationMutex); PrivMutexAbandon(&adapter->lock); /* 发送网络连接成功报文 */ uint8_t notificationReport[4]; notificationReport[0] = requestId; notificationReport[1] = 0x02; notificationReport[2] = 0x01; notificationReport[3] = 0x01; bStatus_t res; while ((res = peripheralNotify(notificationReport, sizeof(notificationReport))) != SUCCESS) { if (res != blePending) { // 发送失败的原因不是阻塞,放弃继续发送 printf("peripheralNotify failed, res: 0x%02x\n", res); break; } else { // 发送失败的原因是阻塞,则等待10ms后再次发送 PrivTaskDelay(10); } } } else { // 如果连接失败 printf("4G connect to server failed\n"); /* 释放互斥锁 */ PrivMutexAbandon(&romConfigurationMutex); PrivMutexAbandon(&adapter->lock); /* 发送网络连接失败报文 */ uint8_t notificationReport[4]; notificationReport[0] = requestId; notificationReport[1] = 0x02; notificationReport[2] = 0x01; notificationReport[3] = 0x02; bStatus_t res; while ((res = peripheralNotify(notificationReport, sizeof(notificationReport))) != SUCCESS) { if (res != blePending) { // 发送失败的原因不是阻塞,放弃继续发送 printf("peripheralNotify failed, res: 0x%02x\n", res); break; } else { // 发送失败的原因是阻塞,则等待10ms后再次发送 PrivTaskDelay(10); } } } return; } /** * @brief 尝试使用配置通过以太网连接到服务器,并且蓝牙响应连接状态报文。 * @param requestId 蓝牙请求报文ID * @note 在解析完成蓝牙请求和写入FLASH配置之后调用该函数 */ void connectServer_Ethernet(uint8_t requestId) { uint8_t destinationIpAddress[16] = {}; // 字符串形式的目的IP地址 uint8_t destinationPort[6] = {}; // 字符串形式的目的端口号 struct Adapter *adapter = AdapterDeviceFindByName(ADAPTER_ETHERNET_NAME); // 查找以太网模块适配器 /* 如果以太网主任务线程仍未启动,则返回连接失败报文 */ if (adapter->adapter_param == NULL) { uint8_t notificationReport[4]; notificationReport[0] = requestId; notificationReport[1] = 0x02; notificationReport[2] = 0x02; notificationReport[3] = 0x02; bStatus_t res; while ((res = peripheralNotify(notificationReport, sizeof(notificationReport))) != SUCCESS) { if (res != blePending) { // 发送失败的原因不是阻塞,放弃继续发送 printf("peripheralNotify failed, res: 0x%02x\n", res); break; } else { // 发送失败的原因是阻塞,则等待10ms后再次发送 PrivTaskDelay(10); } } return; } /* 获取互斥锁 */ PrivMutexObtain(&adapter->lock); // 若其他线程正在使用adapter,则阻塞等待 PrivMutexObtain(&romConfigurationMutex); // 若其他线程正在读取或者写入CFG,则阻塞等待 /* DHCP配置 */ if (CFG->dhcpSwitch_Ethernet == 1) { // 使能DHCP AdapterDeviceSetDhcp(adapter, 1); } else { // 禁用DHCP uint8_t sourceIpAddress[16] = {}; uint8_t sourcePort[6] = {}; uint8_t sourceSubnetMask[16] = {}; uint8_t sourceGateway[16] = {}; memcpy(((struct WchnetSocketConfiguration *)adapter->adapter_param)->sourcePort, CFG->sourcePort_Ethernet, 2); sprintf(sourceIpAddress, "%u.%u.%u.%u", CFG->sourceIpAddress_Ethernet[0], CFG->sourceIpAddress_Ethernet[1], CFG->sourceIpAddress_Ethernet[2], CFG->sourceIpAddress_Ethernet[3]); sprintf(sourcePort, "%u", (unsigned short)CFG->sourcePort_Ethernet[0] | CFG->sourcePort_Ethernet[1] << 8); sprintf(sourceSubnetMask, "%u.%u.%u.%u", CFG->sourceSubnetMask_Ethernet[0], CFG->sourceSubnetMask_Ethernet[1], CFG->sourceSubnetMask_Ethernet[2], CFG->sourceSubnetMask_Ethernet[3]); sprintf(sourceGateway, "%u.%u.%u.%u", CFG->sourceGateway_Ethernet[0], CFG->sourceGateway_Ethernet[1], CFG->sourceGateway_Ethernet[2], CFG->sourceGateway_Ethernet[3]); AdapterDeviceSetAddr(adapter, sourceIpAddress, sourceGateway, sourceSubnetMask); // 配置静态IP地址 AdapterDeviceSetDhcp(adapter, 0); // 禁用DHCP } /* 尝试连接到服务器 */ sprintf(destinationIpAddress, "%u.%u.%u.%u", CFG->destinationIpAddress_Ethernet[0], CFG->destinationIpAddress_Ethernet[1], CFG->destinationIpAddress_Ethernet[2], CFG->destinationIpAddress_Ethernet[3]); sprintf(destinationPort, "%u", (unsigned short)CFG->destinationPort_Ethernet[0] | CFG->destinationPort_Ethernet[1] << 8); printf("-*-*-*-*-AdapterDeviceConnect*-*-*-*-\n"); printf("destinationIpAddress: %s\n", destinationIpAddress); printf("destinationPort: %s\n", destinationPort); printf("-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*--*-*-*\n"); int res = AdapterDeviceConnect(adapter, CLIENT, destinationIpAddress, destinationPort, IPV4); /* 释放互斥锁 */ PrivMutexAbandon(&romConfigurationMutex); PrivMutexAbandon(&adapter->lock); /* 蓝牙反馈连接状态 */ if (res == 0 || res == 0x1D) { // 网络连接成功或之前已经连接 /* 发送网络连接成功报文 */ uint8_t notificationReport[4]; notificationReport[0] = requestId; notificationReport[1] = 0x02; notificationReport[2] = 0x02; notificationReport[3] = 0x01; bStatus_t res; while ((res = peripheralNotify(notificationReport, sizeof(notificationReport))) != SUCCESS) { if (res != blePending) { // 发送失败的原因不是阻塞,放弃继续发送 printf("peripheralNotify failed, res: 0x%02x\n", res); break; } else { // 发送失败的原因是阻塞,则等待10ms后再次发送 PrivTaskDelay(10); } } } else { // 网络连接失败 printf("Ethernet connect to server failed\n"); /* 发送网络连接失败报文 */ uint8_t notificationReport[4]; notificationReport[0] = requestId; notificationReport[1] = 0x02; notificationReport[2] = 0x02; notificationReport[3] = 0x02; bStatus_t res; while ((res = peripheralNotify(notificationReport, sizeof(notificationReport))) != SUCCESS) { if (res != blePending) { // 发送失败的原因不是阻塞,放弃继续发送 printf("peripheralNotify failed, res: 0x%02x\n", res); break; } else { // 发送失败的原因是阻塞,则等待10ms后再次发送 PrivTaskDelay(10); } } } return; } /** * @brief 解析蓝牙请求报文线程 * @param arg 指向蓝牙请求报文的指针 * @return void* 返回值暂无意义 */ void *parseBleRequest(void *arg) { uint8_t *request = (uint8_t *)arg; // 蓝牙请求报文指针 uint8_t requestId = request[0]; // 请求ID uint8_t reportType = request[1]; // 报文类型 uint8_t moduleType = request[2]; // 模块类型 /* 蓝牙反馈ch32v208已收到蓝牙请求 */ uint8_t notificationReport[3]; notificationReport[0] = requestId; notificationReport[1] = 0x01; notificationReport[2] = 0x02; bStatus_t res; while ((res = peripheralNotify(notificationReport, sizeof(notificationReport))) != SUCCESS) { if (res != blePending) { // 发送失败的原因不是阻塞,放弃继续发送 printf("peripheralNotify failed, res: 0x%02x\n", res); break; } else { // 发送失败的原因是阻塞,则等待10ms后再次发送 PrivTaskDelay(10); } } /* 解析蓝牙请求报文 */ PrivMutexObtain(&romConfigurationMutex); // // 若其他线程正在读取或者写入CFG,则阻塞等待 switch (reportType) { /* 4G模块配置目的IP地址、目的端口号、禁用MQTT */ case 0x01: { uint8_t *destinationIpAddress_4G = request + 3; uint8_t *destinationPort_4G = request + 7; uint8_t *mqttSwitch_4G = request + 9; memcpy(CFG->destinationIpAddress_4G, destinationIpAddress_4G, 4); memcpy(CFG->destinationPort_4G, destinationPort_4G, 2); CFG->mqttSwitch_4G = *mqttSwitch_4G; /* 配置写入FLASH */ CFG_ERASE(PAGE_WRITE_START_ADDR, FLASH_PAGE_SIZE); CFG_WRITE(PAGE_WRITE_START_ADDR, Configbuf, MODULE_CFG_LEN); PrivMutexAbandon(&romConfigurationMutex); // 释放互斥锁 connectServer_4G(requestId); // 尝试连接服务器 break; } /* 4G模块配置目的IP地址、目的端口号、使能MQTT、MQTT发布主题、MQTT用户名、MQTT密码、MQTT客户端ID */ case 0x02: { uint8_t *destinationIpAddress_4G = request + 3; uint8_t *destinationPort_4G = request + 7; uint8_t *mqttSwitch_4G = request + 9; uint8_t *mqttTopic_4G = request + 10; uint8_t *mqttUsername_4G = request + 74; uint8_t *mqttPassword_4G = request + 138; uint8_t *mqttClientId_4G = request + 202; memcpy(CFG->destinationIpAddress_4G, destinationIpAddress_4G, 4); memcpy(CFG->destinationPort_4G, destinationPort_4G, 2); CFG->mqttSwitch_4G = *mqttSwitch_4G; memcpy(CFG->mqttTopic_4G, mqttTopic_4G, 64); memcpy(CFG->mqttUsername_4G, mqttUsername_4G, 64); memcpy(CFG->mqttPassword_4G, mqttPassword_4G, 64); memcpy(CFG->mqttClientId_4G, mqttClientId_4G, 24); /* 配置写入FLASH */ CFG_ERASE(PAGE_WRITE_START_ADDR, FLASH_PAGE_SIZE); CFG_WRITE(PAGE_WRITE_START_ADDR, Configbuf, MODULE_CFG_LEN); PrivMutexAbandon(&romConfigurationMutex); // 释放互斥锁 connectServer_4G(requestId); // 尝试连接服务器 break; } /* 以太网模块配置目的IP地址、目的端口号、使能DHCP */ case 0x03: { uint8_t *destinationIpAddress_Ethernet = request + 3; uint8_t *destinationPort_Ethernet = request + 7; uint8_t *dhcpSwitch_Ethernet = request + 9; memcpy(CFG->destinationIpAddress_Ethernet, destinationIpAddress_Ethernet, 4); memcpy(CFG->destinationPort_Ethernet, destinationPort_Ethernet, 2); CFG->dhcpSwitch_Ethernet = *dhcpSwitch_Ethernet; /* 配置写入FLASH */ CFG_ERASE(PAGE_WRITE_START_ADDR, FLASH_PAGE_SIZE); CFG_WRITE(PAGE_WRITE_START_ADDR, Configbuf, MODULE_CFG_LEN); PrivMutexAbandon(&romConfigurationMutex); // 释放互斥锁 connectServer_Ethernet(requestId); // 尝试连接服务器 break; } /* 以太网模块配置目的IP地址、目的端口号、禁用DHCP、源IP地址、源端口号、子网掩码、网关地址 */ case 0x04: { uint8_t *destinationIpAddress_Ethernet = request + 3; uint8_t *destinationPort_Ethernet = request + 7; uint8_t *dhcpSwitch_Ethernet = request + 9; uint8_t *sourceIpAddress_Ethernet = request + 10; uint8_t *sourcePort_Ethernet = request + 14; uint8_t *sourceSubnetMask_Ethernet = request + 16; uint8_t *sourceGateway_Ethernet = request + 20; memcpy(CFG->destinationIpAddress_Ethernet, destinationIpAddress_Ethernet, 4); memcpy(CFG->destinationPort_Ethernet, destinationPort_Ethernet, 2); CFG->dhcpSwitch_Ethernet = *dhcpSwitch_Ethernet; memcpy(CFG->sourceIpAddress_Ethernet, sourceIpAddress_Ethernet, 4); memcpy(CFG->sourcePort_Ethernet, sourcePort_Ethernet, 2); memcpy(CFG->sourceSubnetMask_Ethernet, sourceSubnetMask_Ethernet, 4); memcpy(CFG->sourceGateway_Ethernet, sourceGateway_Ethernet, 4); /* 配置写入FLASH */ CFG_ERASE(PAGE_WRITE_START_ADDR, FLASH_PAGE_SIZE); CFG_WRITE(PAGE_WRITE_START_ADDR, Configbuf, MODULE_CFG_LEN); PrivMutexAbandon(&romConfigurationMutex); // 释放互斥锁 connectServer_Ethernet(requestId); // 尝试连接服务器 break; } /* RS485模块配置波特率、数据位、停止位、校验方式 */ case 0x10: { struct SerialDataCfg rs485Configuration; memset(&rs485Configuration, 0, sizeof(struct SerialDataCfg)); int baudRateOption = request[3]; int dataBitsOption = request[4]; int stopBitsOption = request[5]; int parityOption = request[6]; switch (baudRateOption) { case 1: rs485Configuration.serial_baud_rate = BAUD_RATE_2400; break; case 2: rs485Configuration.serial_baud_rate = BAUD_RATE_4800; break; case 3: rs485Configuration.serial_baud_rate = BAUD_RATE_9600; break; case 4: rs485Configuration.serial_baud_rate = BAUD_RATE_19200; break; case 5: rs485Configuration.serial_baud_rate = BAUD_RATE_38400; break; case 6: rs485Configuration.serial_baud_rate = BAUD_RATE_57600; break; case 7: rs485Configuration.serial_baud_rate = BAUD_RATE_115200; break; case 8: rs485Configuration.serial_baud_rate = BAUD_RATE_230400; break; default: rs485Configuration.serial_baud_rate = BAUD_RATE_9600; break; } switch (dataBitsOption) { case 1: rs485Configuration.serial_data_bits = DATA_BITS_8; break; case 2: rs485Configuration.serial_data_bits = DATA_BITS_9; break; default: rs485Configuration.serial_data_bits = DATA_BITS_8; break; } switch (stopBitsOption) { case 1: rs485Configuration.serial_stop_bits = STOP_BITS_1; break; case 2: rs485Configuration.serial_stop_bits = STOP_BITS_2; break; default: rs485Configuration.serial_stop_bits = STOP_BITS_1; break; } switch (parityOption) { case 1: rs485Configuration.serial_parity_mode = PARITY_NONE; break; case 2: rs485Configuration.serial_parity_mode = PARITY_ODD; break; case 3: rs485Configuration.serial_parity_mode = PARITY_EVEN; break; } struct PrivIoctlCfg ioctl_cfg; ioctl_cfg.ioctl_driver_type = SERIAL_TYPE; ioctl_cfg.args = (void *)&rs485Configuration; int rs485_fd = PrivOpen("/dev/rs485_dev1", O_RDWR); // 打开设备文件 if (0 != PrivIoctl(rs485_fd, OPE_INT, &ioctl_cfg)) { // 进行配置 printf("ioctl uart fd error %d\n", rs485_fd); PrivClose(rs485_fd); return NULL; } /* 配置写入FLASH */ CFG->baudRate_Rs485 = baudRateOption; CFG->dataBits_Rs485 = dataBitsOption; CFG->stopBits_Rs485 = stopBitsOption; CFG->parity_Rs485 = parityOption; CFG_ERASE(PAGE_WRITE_START_ADDR, FLASH_PAGE_SIZE); CFG_WRITE(PAGE_WRITE_START_ADDR, Configbuf, MODULE_CFG_LEN); PrivMutexAbandon(&romConfigurationMutex); break; } /* 报文类型识别失败 */ default: PrivMutexAbandon(&romConfigurationMutex); break; } PrivFree(request); // 释放内存 return NULL; } /** * @brief 启动解析蓝牙请求报文的线程 * @param request 指向蓝牙请求报文的指针 */ void startParseBleRequestTask(uint8_t *request) { /* 启动蓝牙交互的线程 */ pthread_attr_t parseBleRequestTaskAttr; pthread_args_t parseBleRequestTaskArgs; parseBleRequestTaskAttr.schedparam.sched_priority = 16; // 线程优先级 parseBleRequestTaskAttr.stacksize = 2048; // 线程栈大小 parseBleRequestTaskArgs.pthread_name = "parseBleRequestTask"; // 线程名字 parseBleRequestTaskArgs.arg = request; // 线程参数 pthread_t parseBleRequestThread; // 线程ID PrivTaskCreate(&parseBleRequestThread, &parseBleRequestTaskAttr, parseBleRequest, &parseBleRequestTaskArgs); PrivTaskStartup(&parseBleRequestThread); } /** * @brief 命令行显示配置信息 * @return int 返回值暂无意义 * @note 命令形式:ShowConfig */ int ShowConfig(void) { /* 输出配置信息 */ KPrintf("\n*************rom configuration****************\n"); KPrintf("moduleName:\t%s\n", CFG->moduleName); KPrintf("type:\t\t%u\n", CFG->type); /* 4G模块目的IP和端口号配置 */ KPrintf("----------------------------------------------\n"); KPrintf(" 4G \n"); KPrintf("destinationIpAddress:\t\t%u.%u.%u.%u\n", CFG->destinationIpAddress_4G[0], CFG->destinationIpAddress_4G[1], CFG->destinationIpAddress_4G[2], CFG->destinationIpAddress_4G[3]); KPrintf("destinationPort: \t\t%hu\n", (unsigned short)CFG->destinationPort_4G[0] | CFG->destinationPort_4G[1] << 8); /* 4G模块MQTT配置 */ KPrintf("mqttSwitch: \t\t\t%s\n", CFG->mqttSwitch_4G ? "on" : "off"); KPrintf("mqttTopic: \t\t\t%s\n", CFG->mqttTopic_4G); KPrintf("mqttUsername:\t\t\t%s\n", CFG->mqttUsername_4G); KPrintf("mqttPassword:\t\t\t%s\n", CFG->mqttPassword_4G); KPrintf("mqttClientId:\t\t\t%s\n", CFG->mqttClientId_4G); /* Ethernet模块配置 */ KPrintf("----------------------------------------------\n"); KPrintf(" Ethernet \n"); KPrintf("destinationIpAddress: \t\t%u.%u.%u.%u\n", CFG->destinationIpAddress_Ethernet[0], CFG->destinationIpAddress_Ethernet[1], CFG->destinationIpAddress_Ethernet[2], CFG->destinationIpAddress_Ethernet[3]); KPrintf("destinationPort: \t\t%hu\n", (unsigned short)CFG->destinationPort_Ethernet[0] | CFG->destinationPort_Ethernet[1] << 8); KPrintf("dhcpSwitch: \t\t\t%s\n", CFG->dhcpSwitch_Ethernet ? "on" : "off"); KPrintf("sourceIpAddress: \t\t%u.%u.%u.%u\n", CFG->sourceIpAddress_Ethernet[0], CFG->sourceIpAddress_Ethernet[1], CFG->sourceIpAddress_Ethernet[2], CFG->sourceIpAddress_Ethernet[3]); KPrintf("sourcePort: \t\t\t%hu\n", (unsigned short)CFG->sourcePort_Ethernet[0] | CFG->sourcePort_Ethernet[1] << 8); KPrintf("sourceSubnetMask: \t\t%u.%u.%u.%u\n", CFG->sourceSubnetMask_Ethernet[0], CFG->sourceSubnetMask_Ethernet[1], CFG->sourceSubnetMask_Ethernet[2], CFG->sourceSubnetMask_Ethernet[3]); KPrintf("sourceClientGateway: \t\t%u.%u.%u.%u\n", CFG->sourceGateway_Ethernet[0], CFG->sourceGateway_Ethernet[1], CFG->sourceGateway_Ethernet[2], CFG->sourceGateway_Ethernet[3]); /* RS485模块配置 */ KPrintf("----------------------------------------------\n"); KPrintf(" Rs485 \n"); int baudRate_Rs485; int dataBits_Rs485; int stopBits_Rs485; char *parity_Rs485; switch (CFG->baudRate_Rs485) { case 1: baudRate_Rs485 = BAUD_RATE_2400; break; case 2: baudRate_Rs485 = BAUD_RATE_4800; break; case 3: baudRate_Rs485 = BAUD_RATE_9600; break; case 4: baudRate_Rs485 = BAUD_RATE_19200; break; case 5: baudRate_Rs485 = BAUD_RATE_38400; break; case 6: baudRate_Rs485 = BAUD_RATE_57600; break; case 7: baudRate_Rs485 = BAUD_RATE_115200; break; case 8: baudRate_Rs485 = BAUD_RATE_230400; break; default: baudRate_Rs485 = BAUD_RATE_9600; break; } switch (CFG->dataBits_Rs485) { case 1: dataBits_Rs485 = DATA_BITS_8; break; case 2: dataBits_Rs485 = DATA_BITS_9; break; default: dataBits_Rs485 = DATA_BITS_8; break; } switch (CFG->stopBits_Rs485) { case 1: stopBits_Rs485 = STOP_BITS_1; break; case 2: stopBits_Rs485 = STOP_BITS_2; break; default: stopBits_Rs485 = STOP_BITS_1; } switch (CFG->parity_Rs485) { case 1: parity_Rs485 = "NONE"; break; case 2: parity_Rs485 = "ODD"; break; case 3: parity_Rs485 = "EVEN"; break; default: parity_Rs485 = "NONE"; break; } KPrintf("baudRate:\t\t\t%d\n", baudRate_Rs485); KPrintf("dataBits:\t\t\t%d\n", dataBits_Rs485); KPrintf("stopBits:\t\t\t%d\n", stopBits_Rs485); KPrintf("parity:\t\t\t\t%s\n", parity_Rs485); /* 配置有效位校验 */ KPrintf("----------------------------------------------\n"); KPrintf("cfg_flag: 0x%02x 0x%02x\n", CFG->cfgFlag[0], CFG->cfgFlag[1]); KPrintf("**********************************************\n\n"); return 0; } SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), ShowConfig, ShowConfig, list configuration information);