#include "service_timing.h" #include "cmsis_os2.h" #include "sql_fit.h" #include "sys_config.h" #include "rtc_api.h" #include #define ENABLE_STATIC_PRINT_INFO true #define ENABLE_STATIC_PRINT_WARN true #define ENABLE_STATIC_PRINT_ERROR true #if ENABLE_STATIC_PRINT_INFO #define static_print_debug(...) sys_service_log_d(__VA_ARGS__) #else #define static_print_debug(...) #endif #if ENABLE_STATIC_PRINT_WARN #define static_print_warn(...) sys_service_log_w(__VA_ARGS__) #else #define static_print_warn(...) #endif #if ENABLE_STATIC_PRINT_ERROR #define static_print_error(...) sys_service_log_e(__VA_ARGS__) #else #define static_print_error(...) #endif static osTimerId_t g_service_timing_timer = NULL; static tjd_service_timing_timer_info timer_list[24] = {0}; static osMutexId_t g_mutex = NULL; static void get_rtc_time(struct rtc_time *local_time) { struct rtc_class_ops *rtc = tjd_driver_rtc_get_ops(); rtc->get_rtc_time(local_time); } //找到距离 current_time 最近的时间点 static uint32_t find_nearest_time_point(time_point_info current_time) { uint32_t min_diff = -1; uint8_t j = current_time.hour; bool is_nextday = false; //检测当前时间点是否有定时器,适用于开机或时间更新后的初始化。 if(timer_list[j].callback) { if(timer_list[j].time_point.minute > current_time.minute){ min_diff = timer_list[j].time_point.minute-current_time.minute; return min_diff*60; } } j++; //查找下一个 for (int i = 0; i < 24; i++,j++) { if (j >= 24) { j = 0; is_nextday = true; } if(timer_list[j].callback) { if (is_nextday) { min_diff = ((timer_list[j].time_point.hour+24) * 60 + timer_list[j].time_point.minute) - (current_time.hour * 60 + current_time.minute); } else { min_diff = (timer_list[j].time_point.hour * 60 + timer_list[j].time_point.minute) - (current_time.hour * 60 + current_time.minute); } return min_diff*60; } } return 0; } static void service_timing_timer_callback(void *argument) { struct rtc_time local_time; get_rtc_time(&local_time); // 找到距离下次最近的时间触发点 time_point_info current_time = {.hour = local_time.tm_hour, .minute = local_time.tm_min, .second = 0}; uint32_t next_sec = find_nearest_time_point(current_time); osTimerStart(g_service_timing_timer, next_sec * 1000); osMutexAcquire(g_mutex, osWaitForever); if(timer_list[local_time.tm_hour].callback) { timer_list[local_time.tm_hour].callback(timer_list[local_time.tm_hour].data); } osMutexRelease(g_mutex); } void tjd_service_timing_register_timer(tjd_service_timing_timer_info info) { osMutexAcquire(g_mutex, osWaitForever); memcpy(&timer_list[info.time_point.hour], &info, sizeof(tjd_service_timing_timer_info)); osMutexRelease(g_mutex); } void tjd_service_timing_unregister_timer(tjd_service_timing_timer_info info) { if (info.time_point.hour >23 || !info.callback) { static_print_error("tjd_service_timing_unregister_timer parameter error!"); return; } osMutexAcquire(g_mutex, osWaitForever); memset(&timer_list[info.time_point.hour], 0, sizeof(tjd_service_timing_timer_info)); osMutexRelease(g_mutex); } void tjd_service_timing_init(void) { if (g_service_timing_timer == NULL) { g_service_timing_timer = osTimerNew(service_timing_timer_callback, osTimerPeriodic, NULL, NULL); if (!g_service_timing_timer) { static_print_error("tjd_service_timing_init osTimerNew failed"); return; } } // 找到距离下次触发最近的时间点 struct rtc_time local_time; get_rtc_time(&local_time); time_point_info current_time = {.hour = local_time.tm_hour, .minute = local_time.tm_min, .second = 0}; uint32_t next_sec = find_nearest_time_point(current_time); if (g_service_timing_timer) { osStatus_t ret = osTimerStart(g_service_timing_timer, next_sec * 1000); if (ret != osOK) { static_print_error("tjd_service_timing_init osTimerStart failed:%d", ret); return; } } }