2023-06-24 02:20:01 +00:00
|
|
|
|
/*
|
|
|
|
|
* 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>
|
2023-09-04 03:30:48 +00:00
|
|
|
|
//#define BOOT_PER_HOUR
|
2023-06-24 02:20:01 +00:00
|
|
|
|
|
|
|
|
|
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[])
|
|
|
|
|
{
|
2023-09-04 03:30:48 +00:00
|
|
|
|
// rt_device_t dev = rt_device_find("rtc");
|
2023-06-24 02:20:01 +00:00
|
|
|
|
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);
|
2023-06-25 10:49:11 +00:00
|
|
|
|
|
2023-06-24 02:20:01 +00:00
|
|
|
|
if(RT_NULL != alarm)
|
|
|
|
|
{
|
|
|
|
|
rt_alarm_start(alarm);
|
|
|
|
|
LOG_D("alarm started.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* export msh cmd */
|
|
|
|
|
MSH_CMD_EXPORT(alarm_sample,alarm sample);
|
2023-06-25 10:49:11 +00:00
|
|
|
|
|
2023-09-03 11:45:08 +00:00
|
|
|
|
/**
|
|
|
|
|
* 开窗回调
|
|
|
|
|
* @param alarm
|
|
|
|
|
* @param timestamp
|
|
|
|
|
*/
|
2023-06-25 10:49:11 +00:00
|
|
|
|
void poTT_callback(rt_alarm_t alarm, time_t timestamp)
|
|
|
|
|
{
|
2023-08-27 04:31:54 +00:00
|
|
|
|
LOG_I("power UP TT by RTC.");
|
2023-09-03 08:54:23 +00:00
|
|
|
|
timerIsReady();
|
2023-08-21 09:18:07 +00:00
|
|
|
|
setWindowMode();
|
2023-08-31 08:12:44 +00:00
|
|
|
|
initTT();
|
2023-06-25 10:49:11 +00:00
|
|
|
|
}
|
2023-09-03 11:45:08 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 关窗回调
|
|
|
|
|
* @param alarm
|
|
|
|
|
* @param timestamp
|
|
|
|
|
*/
|
2023-06-25 10:49:11 +00:00
|
|
|
|
void pdTT_callback(rt_alarm_t alarm, time_t timestamp)
|
|
|
|
|
{
|
2023-08-27 04:31:54 +00:00
|
|
|
|
LOG_I("power DOWN TT by RTC.");
|
2023-08-31 08:12:44 +00:00
|
|
|
|
clearWindowMode();
|
2023-08-19 06:41:13 +00:00
|
|
|
|
deInitTT();
|
2023-09-03 08:54:23 +00:00
|
|
|
|
//预置开窗会更新多次尝试逻辑,未激活时会始终尝试
|
2023-06-25 10:49:11 +00:00
|
|
|
|
}
|
2023-09-03 11:45:08 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 每小时开窗回调
|
|
|
|
|
* @param alarm
|
|
|
|
|
* @param timestamp
|
|
|
|
|
*/
|
2023-08-22 02:06:12 +00:00
|
|
|
|
void poTT2_callback(rt_alarm_t alarm, time_t timestamp)
|
|
|
|
|
{
|
2023-08-27 04:31:54 +00:00
|
|
|
|
LOG_I("power UP TT by INTERVAL RTC");
|
2023-08-29 11:29:58 +00:00
|
|
|
|
timerIsReady();
|
2023-08-22 02:06:12 +00:00
|
|
|
|
initTT();
|
|
|
|
|
}
|
2023-09-08 08:38:30 +00:00
|
|
|
|
/**
|
|
|
|
|
* 定时更新debug文件名
|
|
|
|
|
* @param alarm
|
|
|
|
|
* @param timestamp
|
|
|
|
|
*/
|
|
|
|
|
void updatelog_callback(rt_alarm_t alarm, time_t timestamp)
|
|
|
|
|
{
|
|
|
|
|
updateDebuglogName();
|
|
|
|
|
}
|
2023-09-04 03:30:48 +00:00
|
|
|
|
|
|
|
|
|
void addDefaultAlarm()
|
2023-06-25 10:49:11 +00:00
|
|
|
|
{
|
|
|
|
|
struct rt_alarm_setup setup;
|
2023-09-04 03:30:48 +00:00
|
|
|
|
struct rt_alarm * alarm = RT_NULL;
|
2023-08-29 11:29:58 +00:00
|
|
|
|
static time_t now;
|
2023-06-25 10:49:11 +00:00
|
|
|
|
struct tm p_tm;
|
|
|
|
|
/* 获取当前时间戳,并把下一秒时间设置为闹钟时间 */
|
|
|
|
|
now = time(NULL);
|
|
|
|
|
gmtime_r(&now, &p_tm);
|
|
|
|
|
|
2023-09-04 03:30:48 +00:00
|
|
|
|
setup.flag = RT_ALARM_HOUR;//小时重复
|
2023-06-25 10:49:11 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2023-09-08 08:38:30 +00:00
|
|
|
|
setup.wktime.tm_min = 1; //每小时的1刻钟启动发送
|
2023-06-25 10:49:11 +00:00
|
|
|
|
|
2023-09-04 03:30:48 +00:00
|
|
|
|
if (RT_NULL != alarm)
|
2023-08-22 02:06:12 +00:00
|
|
|
|
{
|
2023-09-04 03:30:48 +00:00
|
|
|
|
rt_alarm_delete(alarm); //
|
2023-08-22 02:06:12 +00:00
|
|
|
|
}
|
2023-09-08 08:38:30 +00:00
|
|
|
|
alarm = rt_alarm_create(updatelog_callback, &setup);
|
2023-06-25 10:49:11 +00:00
|
|
|
|
|
2023-09-04 03:30:48 +00:00
|
|
|
|
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);
|
2023-08-22 02:06:12 +00:00
|
|
|
|
}
|
2023-09-04 03:30:48 +00:00
|
|
|
|
else {
|
|
|
|
|
LOG_E("Failed to start alarm.");
|
2023-08-22 02:06:12 +00:00
|
|
|
|
}
|
2023-06-25 10:49:11 +00:00
|
|
|
|
|
2023-09-04 03:30:48 +00:00
|
|
|
|
}
|
2023-09-08 08:38:30 +00:00
|
|
|
|
#define BOOT_PER_HOUR
|
2023-09-04 03:30:48 +00:00
|
|
|
|
#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;
|
2023-09-08 08:38:30 +00:00
|
|
|
|
cnt = 0;
|
2023-09-04 03:30:48 +00:00
|
|
|
|
|
|
|
|
|
for (next = _container.head.next; next != &_container.head; next = next->next)
|
2023-08-22 02:06:12 +00:00
|
|
|
|
{
|
2023-09-04 03:30:48 +00:00
|
|
|
|
alarm = rt_list_entry(next, struct rt_alarm, list);
|
|
|
|
|
a[cnt++] = alarm;
|
2023-08-22 02:06:12 +00:00
|
|
|
|
}
|
2023-09-04 03:30:48 +00:00
|
|
|
|
}
|
2023-06-25 10:49:11 +00:00
|
|
|
|
|
2023-09-04 03:30:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* 清空所有RTC闹钟
|
|
|
|
|
*/
|
|
|
|
|
void clearAlarm(void)
|
|
|
|
|
{
|
|
|
|
|
getAllAlarm();
|
2023-09-08 08:38:30 +00:00
|
|
|
|
for (size_t i = 0; i < cnt-indexBegin; ++i)
|
2023-09-04 03:30:48 +00:00
|
|
|
|
{
|
|
|
|
|
rt_alarm_delete(a[i]);
|
2023-08-22 02:06:12 +00:00
|
|
|
|
}
|
2023-06-25 10:49:11 +00:00
|
|
|
|
}
|
2023-09-04 03:30:48 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 关闭rtc闹钟,
|
|
|
|
|
*/
|
|
|
|
|
void stopAlarm()
|
2023-08-08 06:31:16 +00:00
|
|
|
|
{
|
2023-09-04 03:30:48 +00:00
|
|
|
|
getAllAlarm();
|
2023-09-08 08:38:30 +00:00
|
|
|
|
for (size_t i = 0; i < cnt-indexBegin; ++i)
|
2023-09-04 03:30:48 +00:00
|
|
|
|
{
|
|
|
|
|
rt_alarm_stop(a[i]);
|
|
|
|
|
}
|
2023-08-08 06:31:16 +00:00
|
|
|
|
}
|
2023-09-04 03:30:48 +00:00
|
|
|
|
|
2023-06-25 10:49:11 +00:00
|
|
|
|
/**
|
2023-09-04 03:30:48 +00:00
|
|
|
|
* 恢复rtc闹钟,
|
2023-06-25 10:49:11 +00:00
|
|
|
|
*/
|
2023-09-04 03:30:48 +00:00
|
|
|
|
void startAlarm()
|
2023-06-25 10:49:11 +00:00
|
|
|
|
{
|
2023-09-04 03:30:48 +00:00
|
|
|
|
getAllAlarm();
|
2023-09-08 08:38:30 +00:00
|
|
|
|
for (size_t i = 0; i < cnt-indexBegin; ++i)
|
2023-09-04 03:30:48 +00:00
|
|
|
|
{
|
|
|
|
|
rt_alarm_start(a[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-25 10:49:11 +00:00
|
|
|
|
|
2023-09-04 03:30:48 +00:00
|
|
|
|
void addAlarm(uint8_t *din, rt_alarm_callback_t callback)
|
|
|
|
|
{
|
|
|
|
|
struct rt_alarm_setup setup;
|
|
|
|
|
struct rt_alarm * alarm = RT_NULL;
|
2023-08-27 04:31:54 +00:00
|
|
|
|
static time_t now;
|
2023-06-25 10:49:11 +00:00
|
|
|
|
struct tm p_tm;
|
2023-09-04 03:30:48 +00:00
|
|
|
|
|
|
|
|
|
if (alarm != RT_NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2023-06-25 10:49:11 +00:00
|
|
|
|
/* 获取当前时间戳,并把下一秒时间设置为闹钟时间 */
|
2023-09-04 03:30:48 +00:00
|
|
|
|
now = time(NULL) + 10;
|
2023-06-25 10:49:11 +00:00
|
|
|
|
gmtime_r(&now, &p_tm);
|
|
|
|
|
|
2023-09-04 03:30:48 +00:00
|
|
|
|
setup.flag = RT_ALARM_DAILY;
|
2023-06-25 10:49:11 +00:00
|
|
|
|
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;
|
2023-09-04 03:30:48 +00:00
|
|
|
|
setup.wktime.tm_hour = din[0]; //p_tm.tm_hour;
|
|
|
|
|
setup.wktime.tm_min = din[1]; //p_tm.tm_min;
|
2023-06-25 10:49:11 +00:00
|
|
|
|
setup.wktime.tm_sec = 0; //p_tm.tm_sec;
|
|
|
|
|
|
2023-09-04 03:30:48 +00:00
|
|
|
|
alarm = rt_alarm_create(callback, &setup);
|
|
|
|
|
|
|
|
|
|
if (RT_NULL != alarm)
|
|
|
|
|
{
|
2023-09-15 08:36:52 +00:00
|
|
|
|
// rt_alarm_start(alarm);//默认不启动
|
2023-09-04 09:45:03 +00:00
|
|
|
|
// LOG_D("alarm started.");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
LOG_E("Failed to start alarm.");
|
2023-09-04 03:30:48 +00:00
|
|
|
|
}
|
2023-06-25 10:49:11 +00:00
|
|
|
|
}
|
2023-09-04 03:30:48 +00:00
|
|
|
|
|
2023-06-25 10:49:11 +00:00
|
|
|
|
/**
|
2023-09-04 03:30:48 +00:00
|
|
|
|
* 更新rtc闹钟
|
|
|
|
|
* @param t 每个rtc时刻组成的数组,依次对应开窗时段的开始和结束
|
2023-06-25 10:49:11 +00:00
|
|
|
|
*/
|
2023-09-04 03:30:48 +00:00
|
|
|
|
void updateAlarm(uint8_t *t, size_t len)
|
2023-06-25 10:49:11 +00:00
|
|
|
|
{
|
2023-09-04 03:30:48 +00:00
|
|
|
|
clearAlarm();
|
|
|
|
|
for (int var = 0; var < len; var+=4) {
|
|
|
|
|
addAlarm(t+var, poTT_callback);
|
|
|
|
|
addAlarm(t+var+2, pdTT_callback);
|
|
|
|
|
}
|
2023-06-25 10:49:11 +00:00
|
|
|
|
}
|
2023-09-04 03:30:48 +00:00
|
|
|
|
|
2023-09-04 09:45:03 +00:00
|
|
|
|
static int isInAlarm(rt_alarm_t stop, rt_alarm_t start)
|
2023-06-25 10:49:11 +00:00
|
|
|
|
{
|
2023-09-04 09:45:03 +00:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
time_t now = time(RT_NULL);
|
|
|
|
|
|
|
|
|
|
int rst = (now >= tBegin) && (now <= tEnd);
|
|
|
|
|
return rst;
|
2023-06-25 10:49:11 +00:00
|
|
|
|
}
|
2023-07-27 01:34:00 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* check if in the WINs zone
|
|
|
|
|
* @return 1-in,0-not in
|
|
|
|
|
*/
|
|
|
|
|
int isInWindowZone()
|
|
|
|
|
{
|
2023-09-04 03:30:48 +00:00
|
|
|
|
getAllAlarm();
|
2023-07-27 01:34:00 +00:00
|
|
|
|
|
2023-09-04 09:45:03 +00:00
|
|
|
|
int rst = 0;
|
2023-09-08 08:38:30 +00:00
|
|
|
|
for (size_t i = 0; i < cnt-indexBegin; i+=2)
|
2023-07-27 01:34:00 +00:00
|
|
|
|
{
|
2023-09-04 09:45:03 +00:00
|
|
|
|
if(isInAlarm(a[i], a[i+1]))
|
2023-09-04 03:30:48 +00:00
|
|
|
|
{
|
|
|
|
|
LOG_I("is in window zone.");
|
2023-09-04 09:45:03 +00:00
|
|
|
|
rst = 1;
|
|
|
|
|
break;
|
2023-09-04 03:30:48 +00:00
|
|
|
|
}
|
2023-07-27 01:34:00 +00:00
|
|
|
|
}
|
2023-09-04 09:45:03 +00:00
|
|
|
|
return rst;
|
2023-07-27 01:34:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-09-04 03:30:48 +00:00
|
|
|
|
|
|
|
|
|
MSH_CMD_EXPORT(clearAlarm,清空闹钟);
|
2023-08-26 08:49:19 +00:00
|
|
|
|
MSH_CMD_EXPORT(stopAlarm,stop);
|
|
|
|
|
MSH_CMD_EXPORT(startAlarm,start);
|
|
|
|
|
MSH_CMD_EXPORT(isInWindowZone,isInWindow);
|
2023-07-27 01:34:00 +00:00
|
|
|
|
//MSH_CMD_EXPORT(getCurrentTime,getCurrentTime);
|