139 lines
4.2 KiB
C
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;
|
|
}
|
|
}
|
|
}
|