/* * 自然写智能点阵笔嵌入式固件软件 V1.0 * main.c - 主函数入口与RTOS任务创建 * * 功能说明: * 1. 系统硬件初始化(GPIO/SPI/I2C/ADC/DMA) * 2. FreeRTOS内核启动与任务创建 * 3. 各功能模块初始化协调 * 4. 看门狗定时器配置 * 5. 系统错误处理与故障恢复 * * 硬件平台:ARM Cortex-M4F MCU * RTOS:FreeRTOS 10.x */ #include #include #include #include /* FreeRTOS头文件 */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" #include "timers.h" #include "event_groups.h" /* 硬件抽象层头文件 */ #include "hal_gpio.h" #include "hal_spi.h" #include "hal_i2c.h" #include "hal_adc.h" #include "hal_dma.h" #include "hal_wdt.h" #include "hal_flash.h" #include "hal_rtc.h" /* 功能模块头文件 */ #include "camera_driver.h" #include "pressure_sensor.h" #include "led_driver.h" #include "ble_gatt_server.h" #include "dot_decoder.h" #include "power_manager.h" #include "offline_storage.h" /* ========== 任务优先级定义 ========== */ /* 图像采集任务(最高优先级,需要精确的100Hz定时) */ #define TASK_IMAGE_CAPTURE_PRIORITY (configMAX_PRIORITIES - 1) /* 坐标计算任务 */ #define TASK_COORDINATE_PRIORITY (configMAX_PRIORITIES - 2) /* BLE发送任务 */ #define TASK_BLE_SEND_PRIORITY (configMAX_PRIORITIES - 3) /* 电源监测任务(较低优先级) */ #define TASK_POWER_MONITOR_PRIORITY (tskIDLE_PRIORITY + 2) /* 看门狗喂狗任务 */ #define TASK_WATCHDOG_PRIORITY (tskIDLE_PRIORITY + 1) /* ========== 任务栈大小定义(单位:字) ========== */ #define TASK_IMAGE_CAPTURE_STACK_SIZE 512 #define TASK_COORDINATE_STACK_SIZE 1024 #define TASK_BLE_SEND_STACK_SIZE 512 #define TASK_POWER_MONITOR_STACK_SIZE 256 #define TASK_WATCHDOG_STACK_SIZE 128 /* ========== 全局队列与信号量 ========== */ /* 图像数据队列(采集任务 → 坐标计算任务) */ QueueHandle_t g_image_data_queue; /* 坐标数据队列(坐标计算 → BLE发送) */ QueueHandle_t g_coordinate_queue; /* BLE连接状态事件组 */ EventGroupHandle_t g_ble_event_group; /* 系统状态互斥锁 */ SemaphoreHandle_t g_system_mutex; /* ========== 事件位定义 ========== */ #define EVT_BLE_CONNECTED (1 << 0) #define EVT_BLE_DISCONNECTED (1 << 1) #define EVT_PEN_DOWN (1 << 2) #define EVT_PEN_UP (1 << 3) #define EVT_LOW_BATTERY (1 << 4) #define EVT_CHARGING (1 << 5) #define EVT_OTA_START (1 << 6) /* ========== 全局系统状态 ========== */ typedef struct { bool pen_is_down; /* 笔尖是否接触纸面 */ bool ble_connected; /* BLE是否已连接 */ bool is_charging; /* 是否正在充电 */ uint8_t battery_percent; /* 电量百分比 */ uint32_t total_strokes; /* 累计笔画数 */ uint32_t uptime_seconds; /* 运行时长 */ uint8_t error_flags; /* 错误标志位 */ } SystemState; static SystemState g_system_state; /* ========== 任务句柄 ========== */ static TaskHandle_t g_task_image_capture; static TaskHandle_t g_task_coordinate; static TaskHandle_t g_task_ble_send; static TaskHandle_t g_task_power_monitor; static TaskHandle_t g_task_watchdog; /* ========== 函数前向声明 ========== */ static void hardware_init(void); static void create_rtos_objects(void); static void create_tasks(void); static void watchdog_task(void *pvParameters); /* 外部任务函数(各功能模块中实现) */ extern void image_capture_task(void *pvParameters); extern void coordinate_task(void *pvParameters); extern void ble_send_task(void *pvParameters); extern void power_monitor_task(void *pvParameters); /* ========== 主函数 ========== */ /** * 系统入口点 * 完成硬件初始化后启动FreeRTOS调度器 */ int main(void) { /* 步骤1:系统时钟配置(PLL → 168MHz) */ SystemClock_Config(); /* 步骤2:基础硬件初始化 */ hardware_init(); /* 步骤3:LED指示启动中(蓝色闪烁) */ led_set_mode(LED_MODE_BLINK_BLUE); /* 步骤4:初始化全局状态 */ memset(&g_system_state, 0, sizeof(g_system_state)); /* 步骤5:创建RTOS同步对象 */ create_rtos_objects(); /* 步骤6:创建功能任务 */ create_tasks(); /* 步骤7:启动看门狗定时器(超时8秒) */ hal_wdt_init(8000); hal_wdt_start(); /* 步骤8:启动FreeRTOS调度器(不应返回) */ vTaskStartScheduler(); /* 如果到达这里说明调度器启动失败 */ led_set_mode(LED_MODE_SOLID_RED); while (1) { /* 系统错误,死循环 */ } return 0; } /* ========== 硬件初始化 ========== */ /** * 初始化所有硬件外设 */ static void hardware_init(void) { /* GPIO初始化(笔尖接触检测引脚、充电检测引脚) */ hal_gpio_init(); /* SPI初始化(连接CMOS图像传感器,主模式 8MHz) */ hal_spi_init(SPI_PORT_1, SPI_MODE_MASTER, 8000000); /* I2C初始化(连接压力传感器和IMU) */ hal_i2c_init(I2C_PORT_1, 400000); /* 400kHz快速模式 */ /* ADC初始化(电池电压检测,12位分辨率) */ hal_adc_init(ADC_CHANNEL_BATTERY, ADC_RESOLUTION_12BIT); /* DMA初始化(SPI图像数据DMA传输) */ hal_dma_init(DMA_CHANNEL_SPI_RX); /* Flash初始化(离线缓存存储) */ hal_flash_init(); /* RTC初始化(时间戳生成) */ hal_rtc_init(); /* 摄像头传感器初始化 */ camera_driver_init(); /* 压力传感器校准 */ pressure_sensor_init(); pressure_sensor_calibrate(); /* LED驱动初始化 */ led_driver_init(); /* BLE协议栈初始化 */ ble_gatt_server_init(); /* 点阵码解码器初始化 */ dot_decoder_init(); /* 电源管理初始化 */ power_manager_init(); /* 离线存储初始化 */ offline_storage_init(); } /* ========== RTOS对象创建 ========== */ /** * 创建队列、信号量、事件组等RTOS同步对象 */ static void create_rtos_objects(void) { /* * 图像数据队列:采集任务以100Hz频率产生数据 * 队列深度10帧,每帧包含图像元数据(不含原始像素) */ g_image_data_queue = xQueueCreate(10, sizeof(ImageFrameMetadata)); configASSERT(g_image_data_queue != NULL); /* * 坐标数据队列:坐标计算结果 → BLE发送 * 队列深度20,容纳突发计算结果 */ g_coordinate_queue = xQueueCreate(20, sizeof(CoordinatePacket)); configASSERT(g_coordinate_queue != NULL); /* BLE事件组 */ g_ble_event_group = xEventGroupCreate(); configASSERT(g_ble_event_group != NULL); /* 系统状态互斥锁 */ g_system_mutex = xSemaphoreCreateMutex(); configASSERT(g_system_mutex != NULL); } /* ========== 任务创建 ========== */ /** * 创建所有FreeRTOS任务 */ static void create_tasks(void) { BaseType_t ret; /* 图像采集任务(100Hz定时采集CMOS图像) */ ret = xTaskCreate(image_capture_task, "ImgCap", TASK_IMAGE_CAPTURE_STACK_SIZE, NULL, TASK_IMAGE_CAPTURE_PRIORITY, &g_task_image_capture); configASSERT(ret == pdPASS); /* 坐标计算任务(点阵码解码+坐标计算) */ ret = xTaskCreate(coordinate_task, "CoordCalc", TASK_COORDINATE_STACK_SIZE, NULL, TASK_COORDINATE_PRIORITY, &g_task_coordinate); configASSERT(ret == pdPASS); /* BLE发送任务(坐标数据打包+BLE通知发送) */ ret = xTaskCreate(ble_send_task, "BLESend", TASK_BLE_SEND_STACK_SIZE, NULL, TASK_BLE_SEND_PRIORITY, &g_task_ble_send); configASSERT(ret == pdPASS); /* 电源监测任务(电池电压/充电状态/低功耗管理) */ ret = xTaskCreate(power_monitor_task, "PwrMon", TASK_POWER_MONITOR_STACK_SIZE, NULL, TASK_POWER_MONITOR_PRIORITY, &g_task_power_monitor); configASSERT(ret == pdPASS); /* 看门狗喂狗任务 */ ret = xTaskCreate(watchdog_task, "WDT", TASK_WATCHDOG_STACK_SIZE, NULL, TASK_WATCHDOG_PRIORITY, &g_task_watchdog); configASSERT(ret == pdPASS); } /* ========== 看门狗任务 ========== */ /** * 看门狗喂狗任务 * 周期性喂狗,防止系统死锁导致的假死 * 如果各功能任务异常停止,看门狗将触发系统复位 */ static void watchdog_task(void *pvParameters) { (void)pvParameters; TickType_t last_wake_time = xTaskGetTickCount(); while (1) { /* 每2秒喂一次狗(看门狗超时8秒,留足余量) */ hal_wdt_feed(); /* 更新运行时长 */ if (xSemaphoreTake(g_system_mutex, pdMS_TO_TICKS(100)) == pdTRUE) { g_system_state.uptime_seconds += 2; xSemaphoreGive(g_system_mutex); } /* 检查各任务是否正常运行 */ if (eTaskGetState(g_task_image_capture) == eSuspended && g_system_state.pen_is_down) { /* 图像采集任务异常挂起但笔在书写,尝试恢复 */ vTaskResume(g_task_image_capture); } vTaskDelayUntil(&last_wake_time, pdMS_TO_TICKS(2000)); } } /* ========== FreeRTOS回调函数 ========== */ /** * 栈溢出钩子函数 * 任何任务发生栈溢出时被调用 */ void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { /* 记录错误信息到Flash */ g_system_state.error_flags |= 0x01; /* LED红色快闪指示严重错误 */ led_set_mode(LED_MODE_FAST_BLINK_RED); /* 触发系统复位 */ hal_system_reset(); } /** * Malloc失败钩子函数 */ void vApplicationMallocFailedHook(void) { g_system_state.error_flags |= 0x02; led_set_mode(LED_MODE_FAST_BLINK_RED); hal_system_reset(); } /** * 空闲任务钩子函数 * 在CPU空闲时进入低功耗模式以节省电量 */ void vApplicationIdleHook(void) { /* 如果笔没有在书写且BLE空闲,进入轻度睡眠 */ if (!g_system_state.pen_is_down && !g_system_state.ble_connected) { power_enter_light_sleep(); } }