Files
TAIXIN/project/main.c

439 lines
19 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 包含系统配置头文件,提供芯片时钟、电源管理等底层硬件配置 */
#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;
}