Files
TAIXIN/project/main.c

439 lines
19 KiB
C
Raw Normal View History

/* 包含系统配置头文件,提供芯片时钟、电源管理等底层硬件配置 */
#include "sys_config.h"
/* 包含基础头文件集合,提供常用类型定义和宏 */
#include "basic_include.h"
/* 包含ADC模数转换器驱动头文件用于模拟信号采集 */
#include "hal/adc.h"
/* 包含CPU间RPC远程过程调用通信库用于CPU0和CPU1之间的消息传递 */
#include "lib/rpc/cpurpc.h"
/* 包含AT命令解析库用于通过串口发送AT指令进行模块配置 */
#include "lib/atcmd/libatcmd.h"
/* 包含通用AT命令定义提供系统常用的AT命令接口 */
#include "lib/common/atcmd.h"
/* 包含IEEE 802.11无线网络协议定义提供WiFi MAC帧结构等 */
#include "lib/umac/ieee80211.h"
/* 包含低层MACLMAC驱动提供WiFi底层硬件访问接口 */
#include "lib/lmac/lmac.h"
/* 包含BLE低功耗蓝牙演示程序头文件提供蓝牙配网等功能 */
#include "lib/bluetooth/uble/ble_demo.h"
/* 包含lwIP轻量级TCP/IP协议栈错误码定义 */
#include "lwip/err.h"
/* 包含lwIP套接字接口提供类似BSD socket的API */
#include "lwip/sockets.h"
/* 包含lwIP网络域名解析接口提供gethostbyname等DNS功能 */
#include "lwip/netdb.h"
/* 包含lwIP系统抽象层提供线程、信号量等操作系统抽象 */
#include "lwip/sys.h"
/* 包含lwIP IP地址操作接口提供IP地址的解析和转换功能 */
#include "lwip/ip_addr.h"
/* 包含lwIP TCP/IP协议栈核心初始化接口 */
#include "lwip/tcpip.h"
/* 包含以太网网络接口驱动,提供以太网底层收发功能 */
#include "netif/ethernetif.h"
/* 包含DHCP服务器头文件用于设备作为AP时为客户端分配IP地址 */
#include "lib/net/dhcpd/dhcpd.h"
/* 包含网络工具函数提供IP地址转换等网络辅助功能 */
#include "lib/net/utils.h"
/* 包含网络Socket监控模块用于监控socket状态和连接信息 */
#include "lib/net/skmonitor/skmonitor.h"
/* 包含系统配置管理头文件,提供系统参数的读写和存储功能 */
#include "syscfg.h"
/* 包含用户应用层头文件提供FPV、对讲机等应用初始化接口 */
#include "app/user_app.h"
/* 包含CPU1内存管理头文件提供CPU1侧的堆内存获取接口 */
#include "cpu1_mem.h"
/* 外部引用SRAM内存池的起始地址由链接脚本定义 */
extern uint32 srampool_start;
/* 外部引用SRAM内存池的结束地址由链接脚本定义 */
extern uint32 srampool_end;
/* 外部引用PSRAM伪静态RAM内存池的起始地址由链接脚本定义 */
extern uint32 psrampool_start;
/* 外部引用PSRAM内存池的结束地址由链接脚本定义 */
extern uint32 psrampool_end;
/* 定义主循环工作队列结构体,用于定时执行系统主循环任务 */
static struct os_work main_wk;
/* 定义全局系统状态结构体变量,保存系统运行时的各种状态标志 */
struct system_status sys_status;
/* 外部引用系统事件处理函数处理WiFi连接、网络状态等系统事件 */
extern sysevt_hdl_res sys_event_hdl(uint32 event_id, uint32 data, uint32 priv);
/* 外部引用WiFi设备状态查询函数用于获取WiFi模块的调试信息 */
extern void wifi_dev_status(uint32 dev_id);
/* 外部引用系统AT命令初始化函数注册系统支持的AT命令 */
extern void sys_atcmd_init(void);
/* 外部引用WiFi测试模式初始化函数用于产线射频测试 */
extern void sys_wifi_test_mode_init(void);
/* 外部引用WiFi模块初始化函数初始化WiFi硬件和协议栈 */
extern void sys_wifi_init(void);
/* 外部引用:网络初始化函数,配置网络接口和协议参数 */
extern void sys_network_init(void);
/* 外部引用DHCP服务器启动函数在AP模式下为客户端分配IP */
extern void sys_dhcpd_start(void);
/* 外部引用DHCP客户端检查函数检查STA模式下是否成功获取IP */
extern void sys_dhcpc_check(void);
/* CPU间RPC通信初始化函数标记为__init表示仅在系统启动时执行一次 */
static __init void sys_cpurpc_init()
{
/* 初始化CPU0的消息邮箱通信指定邮箱基地址和收发中断号 */
cpu_rpc_init(CPU0_MSGBOX_BASE, CPU_RECV_MAIL_IRQn, CPU_SEND_MAIL_IRQn);
}
/* 系统配置加载函数从Flash中读取保存的系统配置参数 */
__init static void sys_cfg_load(void)
{
/* 尝试从Flash中加载名为"syscfg"的配置数据,如果成功则直接返回 */
if (syscfg_init("syscfg", &sys_cfgs, sizeof(sys_cfgs)) == RET_OK) {
return;
}
/* 如果加载失败(首次启动或数据损坏),打印提示信息 */
os_printf("use default params.\r\n");
/* 使用默认的出厂配置参数填充sys_cfgs结构体 */
syscfg_default();
/* 将默认配置保存到Flash中以便下次启动时可以直接加载 */
syscfg_save();
}
/* 系统调试时间打印函数用于定时打印当前系统时间SNTP同步后 */
static void sys_print_dbgtime(uint32 *buff, uint32 size)
{
#if SYS_APP_SNTP
/* 定义timeval结构体变量用于获取当前的秒和微秒时间 */
struct timeval tv;
/* 调用gettimeofday获取当前系统时间 */
gettimeofday(&tv, 0);
/* 将时间加上8小时东八区/北京时间)的偏移量 */
tv.tv_sec += 8 * 3600;
/* 将时间戳转换为可读的字符串格式并打印 */
os_printf("system time: %s\r\n", ctime((const time_t *)&tv.tv_sec));
#endif
}
/* 系统调试Cache命中率打印函数用于监控CPU Cache的效率 */
static void sys_print_dbgcache(uint32 *buff, uint32 size)
{
/* 仅在调试开关打开时执行Cache统计信息打印 */
if (sys_status.dbg_cache) {
/* 获取CPU侧CSI指令Cache的未命中次数参数1表示打印后重置统计 */
uint32 csi_miss = sys_csi_cache_static(sysctrl_get_cpu_id(), 1);
/* 获取CLD数据Cache的未命中次数参数1表示打印后重置统计 */
uint32 cld_miss = sys_cld_cache_static(1);
/* 根据Cache未命中率动态调整PSRAM效率优化策略 */
sys_psram_eff_static((cld_miss > 20) || (csi_miss > 30));
}
}
/* 系统调试CPU使用率打印函数用于监控各任务的CPU占用情况 */
static void sys_print_dbgtop(uint32 *buff, uint32 size)
{
/* 仅在调试开关打开时执行CPU使用率打印 */
if (sys_status.dbg_top) {
/* 打印CPU各任务的使用率信息参数1表示是否打印详细信息dbg_top==2时 */
cpu_loading_print(sys_status.dbg_top == 2, (struct os_task_info *)buff, size / sizeof(struct os_task_info));
}
}
/* 系统调试Heap内存使用情况打印函数用于监控SRAM和PSRAM的内存分配 */
static void sys_print_dbgheap(uint32 *buff, uint32 size)
{
/* 仅在调试开关打开时执行Heap使用情况打印 */
if (sys_status.dbg_heap) {
/* 打印SRAM Heap的使用状况空闲块数、最大连续空闲空间等 */
sysheap_status(&sram_heap, buff, size / 4, 0);
#ifdef PSRAM_HEAP
/* 如果启用了PSRAM作为Heap也打印PSRAM Heap的使用状况 */
sysheap_status(&psram_heap, buff, size / 4, 0);
#endif
}
}
/* 系统调试WiFi MAC层信息打印函数用于排查WiFi连接问题 */
static void sys_print_dbgumac(uint32 *buff, uint32 size)
{
/* 仅在调试开关打开时执行WiFi调试信息打印 */
if (sys_status.dbg_umac) {
/* 打印WiFi设备设备ID为HG_WIFI0_DEVID的当前状态信息 */
wifi_dev_status(HG_WIFI0_DEVID);
}
}
/* 系统调试网络信息打印函数用于显示当前网络接口的IP地址和DHCP状态 */
static void sys_print_dbgnet(uint32 *buff, uint32 size)
{
/* 定义指向网络接口结构体的指针 */
struct netif *nif;
/* 仅在调试开关打开时执行网络信息打印 */
if (sys_status.dbg_net){
/* 打印分隔线,美化输出格式 */
os_printf("-----------------------------------------------------\r\n");
/* 打印网络信息标题 */
os_printf("Network Info:\r\n");
/* 查找名为"w0"的无线网络接口 */
nif = netif_find("w0");
/* 如果找到无线接口打印其IP地址、子网掩码和网关地址 */
if(nif){
/* 打印WiFi接口的IP配置同时显示是DHCP获取还是静态配置 */
os_printf(" w0: (%s) "IPSTR"/"IPSTR"/"IPSTR"\r\n",
(sys_cfgs.dhcpc_en && sys_status.dhcpc_done)?"DHCP":"Static",
IP2STR_N(nif->ip_addr.addr), IP2STR_N(nif->netmask.addr), IP2STR_N(nif->gw.addr));
}
/* 查找名为"e0"的有线以太网网络接口 */
nif = netif_find("e0");
/* 如果找到以太网接口打印其IP地址、子网掩码和网关地址 */
if(nif){
/* 打印以太网接口的IP配置信息 */
os_printf(" e0: (%s) "IPSTR"/"IPSTR"/"IPSTR"\r\n", sys_cfgs.dhcpc_en?"DHCP":"Static",
IP2STR_N(nif->ip_addr.addr), IP2STR_N(nif->netmask.addr), IP2STR_N(nif->gw.addr));
}
#if IP_NAT
/* 如果启用了NAT网络地址转换打印NAT映射表状态 */
os_printf("-----------------------------------------------------\r\n");
ip4_nat_status();
#endif
/* 如果启用了DHCP服务器打印当前已分配的IP地址池信息 */
if(sys_cfgs.dhcpd_en){
os_printf("-----------------------------------------------------\r\n");
dhcpd_dump_ippool();
}
}
}
/* 系统调试信息汇总打印函数每隔5秒定时调用一次各子打印函数 */
static void sys_dbginfo_print(void)
{
/* 静态变量记录打印间隔计数器用于控制每5秒打印一次 */
static int8 print_interval = 0;
#if 0
/* 静态缓冲区方案(常驻内存,不占用任务栈空间) */
static uint32 _print_buf[256];
#else
/* 局部缓冲区方案(使用任务栈空间,函数返回后自动释放) */
uint32 _print_buf[256];
/* 断言检查确保缓冲区大小不超过1600字节防止任务栈溢出 */
ASSERT(sizeof(_print_buf) < 1600);
#endif
/* 计数器递增当达到5时即5秒后执行一轮调试信息打印 */
if (print_interval++ >= 5) {
/* 打印Cache命中率和PSRAM效率统计 */
sys_print_dbgcache(_print_buf, sizeof(_print_buf));
/* 打印CPU各任务的使用率 */
sys_print_dbgtop(_print_buf, sizeof(_print_buf));
/* 打印SRAM和PSRAM的Heap内存使用情况 */
sys_print_dbgheap(_print_buf, sizeof(_print_buf));
/* 打印WiFi MAC层的调试信息 */
sys_print_dbgumac(_print_buf, sizeof(_print_buf));
/* 打印当前系统时间SNTP同步后 */
sys_print_dbgtime(_print_buf, sizeof(_print_buf));
/* 打印网络接口的IP地址和DHCP信息 */
sys_print_dbgnet(_print_buf, sizeof(_print_buf));
/* 重置计数器开始下一个5秒周期 */
print_interval = 0;
}
}
/* 系统Heap内存布局信息打印函数在启动时显示各内存区域的分配情况 */
__init static void sys_heap_info()
{
/* 打印分隔线 */
os_printf("------------------------------------------------------------\r\n");
/* 打印系统Heap的总体信息总大小和起始地址范围 */
os_printf("System Heaps Info, Total: %d (%p ~ %p)\r\n", SRAM_POOL_SIZE, SRAM_POOL_START, SRAM_POOL_START+SRAM_POOL_SIZE);
/* 定义CPU1 Heap内存区域的起始指针 */
uint8_t *cpu1_heap;
/* 定义CPU1 SKBSocket缓冲区内存池的起始指针 */
uint8_t *skb_heap;
/* 定义CPU1接收缓冲区内存池的起始指针 */
uint8_t *rxbuf_heap;
/* 定义CPU1 Heap内存区域的大小 */
uint32_t cpu1_heap_size;
/* 定义CPU1 SKB内存池的大小 */
uint32_t skb_heap_size;
/* 定义CPU1接收缓冲区内存池的大小 */
uint32_t rxbuf_heap_size;
/* 获取CPU1 Heap内存区域的起始地址和大小 */
cpu1_heap = (uint8_t*)cpu1_heap_get(&cpu1_heap_size);
/* 获取CPU1 SKBSocket Buffer内存池的起始地址和大小 */
skb_heap = (uint8_t*)cpu1_skb_heap_get(&skb_heap_size);
/* 获取CPU1接收缓冲区内存池的起始地址和大小 */
rxbuf_heap = (uint8_t*)cpu1_RXBUF_heap_get(&rxbuf_heap_size);
/* 打印CPU1 Heap的地址范围和大小 */
os_printf("| CPU1 HEAP : %p ~ %p, Size:%-8d |\r\n", cpu1_heap, cpu1_heap+cpu1_heap_size, cpu1_heap_size);
/* 打印CPU1接收缓冲区的地址范围和大小 */
os_printf("| CPU1 RXBUF : %p ~ %p, Size:%-8d |\r\n", rxbuf_heap, rxbuf_heap+rxbuf_heap_size, rxbuf_heap_size);
/* 打印CPU1 SKB内存池的地址范围和大小 */
os_printf("| CPU1 SKBPOOL: %p ~ %p, Size:%-8d |\r\n", skb_heap, skb_heap+skb_heap_size, skb_heap_size);
/* 打印CPU0 AVHEAP音视频堆的地址范围和大小已注释掉 */
//os_printf("| CPU0 AVHEAP : %p ~ %p, Size:%-8d |\r\n", CONFIG_AVHEAP_START, CONFIG_AVHEAP_START+CONFIG_AVHEAP_SIZE, CONFIG_AVHEAP_SIZE);
/* 打印CPU0系统Heap的地址范围和大小 */
os_printf("| CPU0 HEAP : %p ~ %p, Size:%-8d |\r\n", SYS_HEAP_START, SYS_HEAP_START+SYS_HEAP_SIZE, SYS_HEAP_SIZE);
/* 打印分隔线 */
os_printf("------------------------------------------------------------\r\n");
/* 释放CPU1信息查询时分配的内存资源 */
cpu1_info_free();
}
/* 系统主循环函数每1000ms被工作队列调度执行一次 */
static int32 sys_main_loop(struct os_work *work)
{
/* 喂MCU看门狗防止系统死机时看门狗超时复位 */
mcu_watchdog_feed();
/* 调用调试信息打印函数,定时输出系统运行状态 */
sys_dbginfo_print();
#if SYS_NETWORK_SUPPORT
/* 如果系统支持网络功能检查DHCP客户端是否成功获取IP地址 */
sys_dhcpc_check();
#endif
/* 将主循环工作项重新加入队列1000ms后再次执行本函数 */
os_run_work_delay(&main_wk, 1000);
/* 返回0表示函数执行成功 */
return 0;
}
/* 系统应用层初始化函数,根据不同的宏配置启动对应的应用模块 */
__init static void sys_app_init(void)
{
#if SYS_APP_DHCPD && SYS_NETWORK_SUPPORT
/* 如果启用了DHCP服务器且支持网络启动DHCP服务器为连接的客户端分配IP */
sys_dhcpd_start();
#endif
#if SYS_APP_SNTP && SYS_NETWORK_SUPPORT
/* 如果启用了SNTP时间同步且支持网络连接阿里云NTP服务器进行时间同步超时2秒 */
sntp_client_init("ntp.aliyun.com", 2);
#endif
#ifdef SYS_APP_FPV
/* 如果启用了FPV第一人称视角图传应用初始化FPV模块 */
sys_app_fpv_init();
#endif
#ifdef SYS_APP_DEMO
/* 如果启用了通用Demo应用初始化Demo模块 */
sys_app_demo_init();
#endif
#ifdef SYS_APP_IPC
/* 如果启用了IPC网络摄像头应用初始化IPC模块 */
sys_app_ipc_init();
#endif
#ifdef SYS_APP_BBM_LCD
/* 如果启用了BBM婴儿监视器LCD显示端应用初始化LCD显示模块 */
sys_app_bbm_lcd_init();
#endif
#ifdef SYS_APP_WALKIE_TALKIE
/* 如果启用了对讲机应用,初始化对讲机模块 */
sys_app_walkie_talkie_init();
#endif
#ifdef SYS_APP_BBM_CAM
/* 如果启用了BBM婴儿监视器摄像头端应用初始化摄像头模块 */
sys_app_bbm_cam_init();
#endif
#if SYS_APP_BLENC
/* 如果启用了BLE配网功能初始化蓝牙网络配置模块 */
sys_ble_netconfig_init();
#endif
#if SYS_WIFI_PAIR
/* 如果启用了WiFi配对功能初始化WiFi配对模块 */
sys_wifi_pair_init();
#endif
#if SYS_WIFI_PAIR_LED
/* 如果启用了WiFi配对LED指示灯功能初始化配对状态的LED显示 */
sys_wifi_pair_led_init();
#endif
#ifdef SYS_APP_ISP_TUNNING
/* 如果启用了ISP调参应用初始化ISP图像调参模块 */
sys_app_isp_tunning_init();
#endif
}
/* 用户应用初始化函数,用户可在此添加自定义的应用初始化代码 */
__init static void usr_app_init(void)
{
/*
App代码初始化
*/
}
/* 看门狗喂狗循环函数仅在WiFi测试模式下使用防止测试时看门狗复位 */
static int32 watchdog_loop(struct os_work *work)
{
/* 喂MCU看门狗保持系统运行 */
mcu_watchdog_feed();
/* 将看门狗喂狗工作项重新加入队列1000ms后再次执行 */
os_run_work_delay(&main_wk, 1000);
/* 返回0表示函数执行成功 */
return 0;
}
/* 系统主入口函数,芯片上电后首先执行此函数 */
int main(void)
{
/* 设置MCU看门狗超时时间为0禁用MCU看门狗防止调试时意外复位 */
mcu_watchdog_timeout(0);
/* 初始化CPU间RPC通信通道建立CPU0和CPU1之间的消息传递机制 */
sys_cpurpc_init();
/* 打印系统各内存区域的布局信息Heap、PSRAM、SKB池等 */
sys_heap_info();
/* 从Flash加载系统配置参数如果加载失败则使用默认配置并保存 */
sys_cfg_load();
/* 初始化系统事件队列设置队列深度为32个事件 */
sys_event_init(32);
/* 初始化系统AT命令模块注册所有支持的AT命令 */
sys_atcmd_init();
/* 检查系统是否处于WiFi产线测试模式 */
if (system_is_wifi_test_mode()) {
/* 进入WiFi测试模式初始化射频测试所需的硬件和参数 */
sys_wifi_test_mode_init();
/* 测试完成后重启进入正常工作模式 */
system_reboot_normal_mode();
/* 初始化看门狗喂狗工作项绑定watchdog_loop回调函数 */
OS_WORK_INIT(&main_wk, watchdog_loop, 0);
/* 延时1000ms后开始执行看门狗喂狗循环 */
os_run_work_delay(&main_wk, 1000);
}else{
/* 正常工作模式初始化WiFi硬件和协议栈 */
sys_wifi_init();
/* 初始化网络接口配置IP地址和协议参数 */
sys_network_init();
/* 调用所有C++全局对象的构造函数如果项目中包含C++代码) */
do_global_ctors();
/* 根据宏配置初始化对应的应用模块FPV、对讲机等 */
sys_app_init();
/* 执行用户自定义的应用初始化代码 */
usr_app_init();
/* 启动系统事件处理循环接收并分发系统事件WiFi连接、断开等 */
sys_event_take(0xffffffff, sys_event_hdl, 0);
/* 初始化主循环工作项绑定sys_main_loop回调函数 */
OS_WORK_INIT(&main_wk, sys_main_loop, 0);
/* 延时1000ms后开始执行系统主循环 */
os_run_work_delay(&main_wk, 1000);
}
/* 设置PMU电源管理单元看门狗超时时间为0禁用PMU看门狗
sys_wifi_init之后是因为WiFi初始化可能需要较长耗时 */
pmu_watchdog_timeout(0);
/* 主函数返回0实际上RTOS环境下不会执行到此处 */
return 0;
}