mcu_hi3321_watch/tjd/service/service_timing.c
2025-05-26 20:15:20 +08:00

139 lines
4.2 KiB
C

#include "service_timing.h"
#include "cmsis_os2.h"
#include "sql_fit.h"
#include "sys_config.h"
#include "rtc_api.h"
#include <stdlib.h>
#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;
}
}
}