TT12-MCU/applications/alarmer.c
CSSC-WORK\murmur 66377a9450 更新RTC闹钟函数
怪异的现象是添加闹钟后rt_alarm_dump()正常,系统启动后rt_alarm_dump()异常,时钟加了+8
2023-09-04 11:30:48 +08:00

297 lines
6.5 KiB
C
Raw 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.

/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-06-19 murmur the first version
*/
/*
** 程序清单:这是一个 RTC 设备使用例程
** 例程导出了 alarm_sample 命令到控制终端
** 命令调用格式alarm_sample
** 程序功能设置RTC时间创建闹钟模式每秒触发启动闹钟
**/
#include <rtthread.h>
#include <rtdevice.h>
#define LOG_TAG "alarm"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>
//#define BOOT_PER_HOUR
void user_alarm_callback(rt_alarm_t alarm, time_t timestamp)
{
rt_kprintf("user alarm callback function.\n");
}
void alarm_sample(int argc, char *argv[])
{
// rt_device_t dev = rt_device_find("rtc");
struct rt_alarm_setup setup;
struct rt_alarm * alarm = RT_NULL;
static time_t now;
struct tm p_tm;
if (alarm != RT_NULL)
return;
/* 获取当前时间戳,并把下一秒时间设置为闹钟时间 */
now = time(NULL) + 10;
gmtime_r(&now,&p_tm);
setup.flag = RT_ALARM_DAILY;
setup.wktime.tm_year = p_tm.tm_year;
setup.wktime.tm_mon = p_tm.tm_mon;
setup.wktime.tm_mday = p_tm.tm_mday;
setup.wktime.tm_wday = p_tm.tm_wday;
setup.wktime.tm_hour = atoi(argv[1]);//p_tm.tm_hour;
setup.wktime.tm_min = 0;//p_tm.tm_min;
setup.wktime.tm_sec = 0;//p_tm.tm_sec;
alarm = rt_alarm_create(user_alarm_callback, &setup);
if(RT_NULL != alarm)
{
rt_alarm_start(alarm);
LOG_D("alarm started.");
}
}
/* export msh cmd */
MSH_CMD_EXPORT(alarm_sample,alarm sample);
/**
* 开窗回调
* @param alarm
* @param timestamp
*/
void poTT_callback(rt_alarm_t alarm, time_t timestamp)
{
LOG_I("power UP TT by RTC.");
timerIsReady();
setWindowMode();
initTT();
}
/**
* 关窗回调
* @param alarm
* @param timestamp
*/
void pdTT_callback(rt_alarm_t alarm, time_t timestamp)
{
LOG_I("power DOWN TT by RTC.");
clearWindowMode();
deInitTT();
//预置开窗会更新多次尝试逻辑,未激活时会始终尝试
}
/**
* 每小时开窗回调
* @param alarm
* @param timestamp
*/
void poTT2_callback(rt_alarm_t alarm, time_t timestamp)
{
LOG_I("power UP TT by INTERVAL RTC");
timerIsReady();
initTT();
}
void addDefaultAlarm()
{
struct rt_alarm_setup setup;
struct rt_alarm * alarm = RT_NULL;
static time_t now;
struct tm p_tm;
/* 获取当前时间戳,并把下一秒时间设置为闹钟时间 */
now = time(NULL);
gmtime_r(&now, &p_tm);
setup.flag = RT_ALARM_HOUR;//小时重复
setup.wktime.tm_year = p_tm.tm_year;
setup.wktime.tm_mon = p_tm.tm_mon;
setup.wktime.tm_mday = p_tm.tm_mday;
setup.wktime.tm_wday = p_tm.tm_wday;
setup.wktime.tm_hour = 1; //整点
setup.wktime.tm_min = 0; //p_tm.tm_min;
setup.wktime.tm_sec = 0; //p_tm.tm_sec;
setup.wktime.tm_min = 15; //每小时的1刻钟启动发送
if (RT_NULL != alarm)
{
rt_alarm_delete(alarm); //
}
alarm = rt_alarm_create(poTT2_callback, &setup);
if (alarm != RT_NULL) {
rt_alarm_start(alarm);
// LOG_D("alarm %d(%02d:%02d) started.",var+1,alarm[var]->wktime.tm_hour+8,alarm[var]->wktime.tm_min);
}
else {
LOG_E("Failed to start alarm.");
}
}
#ifdef BOOT_PER_HOUR
INIT_APP_EXPORT(addDefaultAlarm);
#endif
extern struct rt_alarm_container _container;
static rt_alarm_t a[50];
static size_t cnt = 0;
#ifdef BOOT_PER_HOUR
static size_t indexBegin=1;
#else
static size_t indexBegin=0;
#endif
/**
*获取所有RTC闹钟不含预置闹钟
*/
void getAllAlarm()
{
rt_list_t *next;
rt_alarm_t alarm;
cnt = indexBegin;
for (next = _container.head.next; next != &_container.head; next = next->next)
{
alarm = rt_list_entry(next, struct rt_alarm, list);
a[cnt++] = alarm;
}
}
/**
* 清空所有RTC闹钟
*/
void clearAlarm(void)
{
getAllAlarm();
for (size_t i = indexBegin; i < cnt; ++i)
{
rt_alarm_delete(a[i]);
}
}
/**
* 关闭rtc闹钟
*/
void stopAlarm()
{
getAllAlarm();
for (size_t i = indexBegin; i < cnt; ++i)
{
rt_alarm_stop(a[i]);
}
}
/**
* 恢复rtc闹钟
*/
void startAlarm()
{
getAllAlarm();
for (size_t i = indexBegin; i < cnt; ++i)
{
rt_alarm_start(a[i]);
}
}
void addAlarm(uint8_t *din, rt_alarm_callback_t callback)
{
struct rt_alarm_setup setup;
struct rt_alarm * alarm = RT_NULL;
static time_t now;
struct tm p_tm;
if (alarm != RT_NULL)
return;
/* 获取当前时间戳,并把下一秒时间设置为闹钟时间 */
now = time(NULL) + 10;
gmtime_r(&now, &p_tm);
setup.flag = RT_ALARM_DAILY;
setup.wktime.tm_year = p_tm.tm_year;
setup.wktime.tm_mon = p_tm.tm_mon;
setup.wktime.tm_mday = p_tm.tm_mday;
setup.wktime.tm_wday = p_tm.tm_wday;
setup.wktime.tm_hour = din[0]; //p_tm.tm_hour;
setup.wktime.tm_min = din[1]; //p_tm.tm_min;
setup.wktime.tm_sec = 0; //p_tm.tm_sec;
alarm = rt_alarm_create(callback, &setup);
if (RT_NULL != alarm)
{
rt_alarm_start(alarm);
LOG_D("alarm started.");
}
rt_alarm_dump();
}
/**
* 更新rtc闹钟
* @param t 每个rtc时刻组成的数组依次对应开窗时段的开始和结束
*/
void updateAlarm(uint8_t *t, size_t len)
{
clearAlarm();
for (int var = 0; var < len; var+=4) {
addAlarm(t+var, poTT_callback);
addAlarm(t+var+2, pdTT_callback);
}
}
static int isInAlarm(time_t now, rt_alarm_t start, rt_alarm_t stop)
{
struct tm *alBegin = &start->wktime;
alBegin->tm_hour += 8;
time_t tBegin = mktime(alBegin);
struct tm *alEnd = &stop->wktime;
alEnd->tm_hour += 8;
time_t tEnd = mktime(alEnd);
// LOG_D("%ld-%ld", (long)tBegin,(long)tEnd);
return (int)(now >= tBegin && now <= tEnd);
}
/**
* check if in the WINs zone
* @return 1-in,0-not in
*/
int isInWindowZone()
{
struct timeval tv;
gettimeofday(&tv, NULL);
time_t now = (long) tv.tv_sec;
// LOG_D("now = %ld", now);
getAllAlarm();
for (size_t i = indexBegin; i < cnt; i+=2)
{
if(isInAlarm(now, a[i], a[i+1]))
{
LOG_I("is in window zone.");
return 1;
}
else {
continue;
}
}
return 0;
}
MSH_CMD_EXPORT(clearAlarm,);
MSH_CMD_EXPORT(stopAlarm,stop);
MSH_CMD_EXPORT(startAlarm,start);
MSH_CMD_EXPORT(isInWindowZone,isInWindow);
//MSH_CMD_EXPORT(getCurrentTime,getCurrentTime);