one_channel_hub 移植到CH584M MCU平台(移除WiFi/网络相关代码)
一、移植前准备
1. 核心背景
- CH584M特性:沁恒微的低功耗MCU,基于RISC-V架构,内置BLE 5.0,无WiFi外设,需适配其裸机/轻量级RTOS开发环境(MounRiver Studio + 沁恒官方CH58x SDK)。
- 原仓库核心模块:LoRa射频驱动(sx126x/llcc68/lr11xx)、RAL(Radio Abstraction Layer)、LoRaHub HAL层是核心;WiFi/HTTP/UDP/Web/SNTP/BLE配网是需移除的网络相关模块。
2. 环境搭建
- 安装MounRiver Studio(MRS),导入CH584M官方SDK(包含GPIO/SPI/定时器/中断等底层驱动)。
- 从原仓库拉取代码:
git clone https://github.com/Lora-net/one_channel_hub。
二、代码裁剪:移除网络相关模块
1. 删除网络相关文件
删除原仓库中以下文件/目录(WiFi/HTTP/Web/配网相关):
# 核心删除项 one_channel_hub/lorahub/main/wifi.c one_channel_hub/lorahub/main/wifi.h one_channel_hub/lorahub/main/http_server.c/h (若有) one_channel_hub/lorahub/main/udp_client.c/h (Packet Forwarder网络传输) one_channel_hub/components/wifi_provisioning/ (BLE配网) one_channel_hub/doc/ (非代码,可选删除) one_channel_hub/tests/ (测试脚本,可选删除) one_channel_hub/tools/ (工具脚本,可选删除)2. 移除代码中网络相关引用
(1)修改lorahub/main/main.c
删除WiFi初始化、HTTP服务器、UDP客户端相关代码,保留LoRa核心初始化逻辑:
// 原代码中需删除的片段(示例)#include"wifi.h"// 移除WiFi头文件#include"http_server.h"// 移除HTTP头文件// 删除WiFi初始化调用// wifi_sta_init(false);// http_server_start(); // 移除HTTP服务器启动// udp_client_init(); // 移除UDP客户端初始化// 保留LoRa核心初始化lgw_connect();lgw_radio_setup();(2)修改components/liblorahub/lorahub_hal.c
移除ESP32网络/FreeRTOS相关依赖,删除WiFi状态关联逻辑:
// 移除ESP32网络相关头文件#include<esp_netif.h>// 删除#include<freertos/FreeRTOS.h>// 删除#include<freertos/event_groups.h>// 删除// 移除WiFi状态相关宏/变量(如WIFI_CONNECTED_BIT等)// 删除所有与WiFi状态联动的逻辑(如原代码中依赖WiFi连接的Packet Forwarder发送)(3)修改编译配置
原仓库基于ESP-IDF的menuconfig配置,需删除WiFi/网络相关配置项:
- 删除
sdkconfig.defaults中CONFIG_WIFI_*、CONFIG_HTTP_*、CONFIG_UDP_*等宏。 - 若使用Makefile/CMake,移除WiFi/网络相关的编译依赖(如
esp_wifi、esp_http_server等组件)。
三、CH584M底层驱动适配(核心步骤)
原有代码基于ESP32的底层(GPIO/SPI/定时器/中断),需替换为CH584M的SDK接口。
1. SPI驱动适配(LoRa射频通信)
CH584M的SPI外设替代ESP32的SPI驱动,示例如下(适配SX1262):
// CH584M SPI初始化(替代原esp32 spi_bus_initialize)#include"CH58x_common.h"#defineSPI_LORA_SCLK_PINGPIO_Pin_2// 自定义引脚,需与硬件匹配#defineSPI_LORA_MOSI_PINGPIO_Pin_3#defineSPI_LORA_MISO_PINGPIO_Pin_4#defineSPI_LORA_NSS_PINGPIO_Pin_5#defineSPI_LORA_RESET_PINGPIO_Pin_6#defineSPI_LORA_DIO1_PINGPIO_Pin_7#defineSPI_LORA_BUSY_PINGPIO_Pin_8// SPI初始化函数voidlora_spi_init(void){// 配置SPI引脚为复用功能GPIO_SetFunc(SPI_LORA_SCLK_PIN,GPIO_FUN_SPI0_SCK);GPIO_SetFunc(SPI_LORA_MOSI_PIN,GPIO_FUN_SPI0_MOSI);GPIO_SetFunc(SPI_LORA_MISO_PIN,GPIO_FUN_SPI0_MISO);// 配置NSS为GPIO输出(软件控制)GPIO_ModeCfg(SPI_LORA_NSS_PIN,GPIO_ModeOut_PP_5mA);GPIO_SetBits(SPI_LORA_NSS_PIN);// 片选默认拉高// SPI0配置:主机模式,时钟极性0,相位0,速率1MHzSPI0_MasterDefInit();SPI0_SetClockDiv(SPI_CLK_DIV_16);// CH584M主频60MHz,分频后3.75MHz(可调整)}// SPI读写函数(替代原ESP32 spi_device_transmit)uint8_tspi_write_read(uint8_ttx_data){while(SPI0_GetTxFIFOFreeNum()==0);SPI0_SendData(tx_data);while(SPI0_GetRxFIFOCount()==0);returnSPI0_RecvData();}// LoRa片选控制voidlora_nss_set(uint8_tstate){if(state)GPIO_SetBits(SPI_LORA_NSS_PIN);elseGPIO_ResetBits(SPI_LORA_NSS_PIN);}2. GPIO/中断适配(LoRa DIO1/BUSY/RESET)
CH584M的GPIO中断替代ESP32的中断逻辑(以DIO1中断为例,处理LoRa接收完成):
// GPIO初始化voidlora_gpio_init(void){// RESET引脚:输出GPIO_ModeCfg(SPI_LORA_RESET_PIN,GPIO_ModeOut_PP_5mA);GPIO_SetBits(SPI_LORA_RESET_PIN);// 复位默认拉高// BUSY引脚:输入GPIO_ModeCfg(SPI_LORA_BUSY_PIN,GPIO_ModeIN_PU);// DIO1引脚:输入+中断(上升沿触发)GPIO_ModeCfg(SPI_LORA_DIO1_PIN,GPIO_ModeIN_PU);GPIO_ITModeCfg(SPI_LORA_DIO1_PIN,GPIO_IT_RisingEdge);// 上升沿中断PFIC_EnableIRQ(GPIO_IRQn);// 使能GPIO中断}// GPIO中断服务函数__interrupt__attribute__((used))voidGPIO_IRQHandler(void){if(GPIO_GetITFlag(SPI_LORA_DIO1_PIN)){GPIO_ClearITFlag(SPI_LORA_DIO1_PIN);// 清除中断标志lora_rx_handler();// 调用LoRa接收处理函数(需实现)}}3. 定时器适配(替代ESP32的esp_timer)
CH584M的通用定时器替代ESP32的高精度定时器,用于LoRa时序控制:
// 定时器初始化(1ms中断)voidtimer_init(void){TMR_TimerCfg(TMR0,TMR_MODE_SYSCLK,TMR_CLK_DIV_60);// 60MHz/60=1MHzTMR_TimerCountCfg(TMR0,1000,TMR_COUNT_MODE_DOWN);// 1MHz计数1000次=1msTMR_ITCfg(TMR0,ENABLE,TMR_IT_END_CNT);// 计数结束中断PFIC_EnableIRQ(TMR0_IRQn);// 使能定时器中断TMR_TimerRun(TMR0,ENABLE);// 启动定时器}// 定时器中断服务函数(用于LoRa超时/轮询)__interrupt__attribute__((used))voidTMR0_IRQHandler(void){if(TMR_GetITFlag(TMR0,TMR_IT_END_CNT)){TMR_ClearITFlag(TMR0,TMR_IT_END_CNT);// 此处添加LoRa定时处理逻辑(如轮询BUSY状态、超时检测)}}4. RAL层适配(Radio Abstraction Layer)
原RAL层基于ESP32的硬件抽象,需修改为CH584M的接口:
// 修改 components/smtc_ral/ral_sx126x.c 中的硬件操作函数// 示例:替换ESP32的SPI读写为CH584M的SPI函数ral_status_tral_sx126x_write(constral_t*ral,constuint16_taddr,constuint8_t*data,constuint16_tsize){lora_nss_set(0);// 拉低片选spi_write_read(0x02);// 写命令spi_write_read((addr>>8)&0xFF);// 地址高字节spi_write_read(addr&0xFF);// 地址低字节for(uint16_ti=0;i<size;i++){spi_write_read(data[i]);// 写数据}lora_nss_set(1);// 拉高片选returnRAL_STATUS_OK;}ral_status_tral_sx126x_read(constral_t*ral,constuint16_taddr,uint8_t*data,constuint16_tsize){lora_nss_set(0);// 拉低片选spi_write_read(0x03);// 读命令spi_write_read((addr>>8)&0xFF);// 地址高字节spi_write_read(addr&0xFF);// 地址低字节for(uint16_ti=0;i<size;i++){data[i]=spi_write_read(0xFF);// 读数据}lora_nss_set(1);// 拉高片选returnRAL_STATUS_OK;}// 替换复位函数为CH584M的GPIO操作ral_status_tral_sx126x_reset(constral_t*ral){GPIO_ResetBits(SPI_LORA_RESET_PIN);DelayMs(10);// CH584M的延时函数GPIO_SetBits(SPI_LORA_RESET_PIN);DelayMs(50);returnRAL_STATUS_OK;}四、LoRaHub核心逻辑适配
1. 移除Packet Forwarder的网络传输
原Packet Forwarder通过UDP将LoRa数据包发送到LNS(网络服务器),需删除该逻辑,改为本地处理(如串口打印数据包):
// 修改 components/liblorahub/lorahub_hal_rx.c 中的接收处理函数voidlgw_hal_rx_packet_process(void){structlgw_pkt_rx_srx_pkt;if(lgw_hal_rx_read(&rx_pkt)==LGW_HAL_SUCCESS){// 原逻辑:通过UDP发送到LNS → 删除// 新逻辑:串口打印数据包(CH584M的UART)uart_printf("LoRa RX Packet: ");for(uint16_ti=0;i<rx_pkt.size;i++){uart_printf("%02X ",rx_pkt.payload[i]);}uart_printf("\r\n");}}2. 移除FreeRTOS依赖
原代码使用FreeRTOS的事件组、任务等,CH584M若用裸机,需替换为轮询/中断逻辑:
// 原FreeRTOS任务(示例)// xTaskCreate(lora_task, "lora_task", 4096, NULL, 5, NULL);// 替换为裸机主循环intmain(void){// 初始化CH584M外设SystemInit();// 官方SDK初始化uart_init();// 串口初始化(用于调试)lora_spi_init();lora_gpio_init();timer_init();// 初始化LoRalgw_connect();lgw_radio_setup();lgw_hal_rx_config();// 配置LoRa接收参数(频率、扩频因子等)// 裸机主循环while(1){lgw_hal_rx_packet_process();// 处理接收的LoRa数据包DelayMs(10);// 短延时,降低CPU占用}}五、编译与调试
1. 编译配置
- 在MounRiver Studio中创建CH584M工程,将裁剪后的核心代码(LoRa驱动、RAL、HAL层)加入工程。
- 配置编译选项:
- 编译器:RISC-V GCC(MRS内置)。
- 宏定义:添加
CONFIG_RADIO_TYPE_SX1262(根据实际使用的LoRa射频芯片)、CH584M等。 - 链接脚本:使用CH584M官方链接脚本,适配内存布局。
2. 调试注意事项
- 硬件接线:确认CH584M与LoRa模块(如SX1262)的SPI、GPIO引脚连接正确。
- 射频参数:根据实际硬件配置LoRa的频率、扩频因子、带宽等(修改
lorahub_hal.c中的rxrf_conf、rxif_conf)。 - 串口调试:通过CH584M的UART打印调试信息,确认LoRa初始化、接收/发送是否正常。
六、关键注意点
- 射频驱动兼容性:CH584M的SPI速率需匹配LoRa芯片(SX126x建议≤10MHz),需调整
SPI0_SetClockDiv。 - 中断优先级:CH584M的GPIO中断、定时器中断优先级需合理配置,避免冲突。
- 功耗优化:CH584M支持低功耗模式,可在LoRa休眠时进入MCU低功耗,降低功耗。
- 代码裁剪彻底性:需删除所有ESP32特有头文件(如
esp_log.h、freertos/*.h),替换为CH584M的日志/调试方式(如串口打印)。
通过以上步骤,可将one_channel_hub的核心LoRa功能移植到CH584M平台,并彻底移除WiFi/网络相关代码,实现裸机环境下的LoRa数据包接收/处理。