AWTK之时间设置(嵌入式平台)篇
前言:在嵌入式平台需要提供并设置获取当前日期和时间的函数,否则相关的功能(如时钟控件)将无法正常工作。一、date_time_global_init_ex(&s_date_time_vtable);static ret_t date_time_get_now_impl(date_time_t* dt){st_rtc_time_t rtcTime;st_rtc_time_t localTim
·
前言:
当AWTK界面被应用到嵌入式平台(如STM32中),需要提供并设置获取当前日期和时间的函数,否则相关的功能(如时钟控件)将无法正常工作。
一、函数
date_time_global_init_ex(&s_date_time_vtable);

二、代码实现:
平台:STM32
物联网操作系统:RT_Thread
编译:IAR
此处注册RTC设备:略
RTC获取时间部分
RTC.c
/** @brief RTC设备的名称 */
#define RTC_DEVICE_NAME "RTC"
/** @brief 配置RTC设备硬件时间直接存储、使用当地时间 */
#define CONFIG_RTC_TIME_IS_LOCAL (0)
// Table of month length (in days) for the Un-leap-year
PRIVATE const bf_uint8_t s_mdaysUnleapYear[] =
{
0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U
};
// Table of month length (in days) for the Leap-year
PRIVATE const bf_uint8_t s_mdaysLeapYear[] =
{
0U, 31U, 29U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U
};
/**
* @brief RTC时间数据的类型定义
*/
typedef struct st_rtc_time
{
bf_uint16_t year; /**< 年,例如2016 */
bf_uint16_t month; /**< 月, (1-12) */
bf_uint16_t day; /**< 日, (1-31) */
bf_uint16_t hour; /**< 小时, (0-23) */
bf_uint16_t minute; /**< 分钟, (0-59) */
bf_uint16_t second; /**< 秒, (0-59) */
} st_rtc_time_t, *pst_rtc_time_t;
#define ReturnValIfFail(expr, val) do \
{ \
if (CONFIG_GLOBAL_ENABLE_CHECKS && (!(expr))) \
{ \
LOG_WarningLine("expr: ("#expr") failed."); \
return (val); \
} \
} \
while (0)
pq_bool_t RTC_CheckDateTimeValid(pst_rtc_time_t datetime)
{
pq_uint_t mdays;
if (PQ_NULL == datetime)
return PQ_FALSE;
if ((datetime->month > 12U) || (datetime->month < 1U)
|| (datetime->day > 31U) || (datetime->day < 1U)
|| (datetime->hour >= 24U) || (datetime->minute >= 60U) || (datetime->second >= 60U))
{
return PQ_FALSE;
}
if ((datetime->year & 3U))
{
mdays = s_mdaysUnleapYear[datetime->month];
}
else
{
mdays = s_mdaysLeapYear[datetime->month];
}
if (datetime->day > mdays)
return PQ_FALSE;
return PQ_TRUE;
}
/*******************************************************************************
* Private Functions
******************************************************************************/
PRIVATE void RtcConvertDatetimeToNewtm(pst_rtc_time_t datetime, bf_int_t secondsToAdjust, struct tm *newtm)
{
// NOTE: The 32-bit interface supports years from 1900 up to 2035 and uses a 32-bit integer for time_t,
// The 64-bit interface supports years from -9999 up to 9999 and uses a signed
// long long for time_t. The type and function have names like __time64_t,
// __time64, etc.
// pls see IAR docs for more details.
time_t timestamp;
struct tm timeInstance;
struct tm *timeInstancePtr;
memzero(&timeInstance, sizeof(timeInstance));
timeInstance.tm_year = datetime->year - 1900;
timeInstance.tm_mon = datetime->month - 1;
timeInstance.tm_mday = datetime->day;
timeInstance.tm_hour = datetime->hour;
timeInstance.tm_min = datetime->minute;
timeInstance.tm_sec = datetime->second;
timestamp = mktime(&timeInstance);
// TIP: 目前我们并未定制IAR的库,因此以下的处理仍为非线程安全函数,需要进入调度临界区
rt_enter_critical();
{
bf_uint_t diffSeconds;
diffSeconds = abs(secondsToAdjust);
if (secondsToAdjust > 0)
{
timestamp += diffSeconds;
}
else
{
timestamp -= diffSeconds;
}
timeInstancePtr = gmtime(×tamp);
memcpy(newtm, timeInstancePtr, sizeof(*timeInstancePtr));
}
rt_exit_critical();
}
PRIVATE void RtcConvertTmToRtctime(struct tm *oldtm, pst_rtc_time_t datetime)
{
datetime->year = oldtm->tm_year + 1900;
datetime->month = oldtm->tm_mon + 1;
datetime->day = oldtm->tm_mday;
datetime->hour = oldtm->tm_hour;
datetime->minute = oldtm->tm_min;
datetime->second = oldtm->tm_sec;
}
PRIVATE void RtcAdjustDateTime(pst_rtc_time_t datetime, bf_int_t secondsToAdjust)
{
struct tm newtm;
if (0 == secondsToAdjust)
return;
RtcConvertDatetimeToNewtm(datetime, secondsToAdjust, &newtm);
RtcConvertTmToRtctime(&newtm, datetime);
}
/*******************************************************************************
* Private Functions
******************************************************************************/
PQ_bool_t RTC_GetLocalTime(pst_rtc_time_t localTime, pst_rtc_time_t knownUtcTime)
{
st_rtc_time_t rtcTime;
bf_int_t secondsToAdjust;
ReturnValIfFail(PQ_NULL != localTime, PQ_FALSE);
if (PQ_NULL == knownUtcTime)
{
rt_device_t dev;
dev = rt_device_find(RTC_DEVICE_NAME);
rt_device_open(dev, RT_DEVICE_FLAG_RDWR);
memzero(&rtcTime, sizeof(rtcTime));
rt_device_control(dev, RTC_IOCTL_GET_TIME, &rtcTime);
rt_device_close(dev);
}
else
{
memcpy(&rtcTime, knownUtcTime, sizeof(*knownUtcTime));
}
if (!RTC_CheckDateTimeValid(&rtcTime))
return PQ_FALSE;
memcpy(localTime, &rtcTime, sizeof(rtcTime));
#if CONFIG_RTC_TIME_IS_LOCAL
if (PQ_NULL == knownUtcTime)
{
// 从RTC硬件读取时间,在此模式下,已经是当地时间了,无需调整
secondsToAdjust = 0;
}
else
{
// 用户主动传入的时间,属于UTC时间,仍需要进行转换
rt_enter_critical();
secondsToAdjust = s_rtcCorePrivInfo.secondsToAdjust;
rt_exit_critical();
}
#else
rt_enter_critical();
secondsToAdjust = s_rtcCorePrivInfo.secondsToAdjust;
rt_exit_critical();
#endif
RtcAdjustDateTime(localTime, secondsToAdjust);
return PQ_TRUE;
}
AWTK设置时间部分!!
AWTK设置时间部分:
static ret_t date_time_get_now_impl(date_time_t* dt)
{
st_rtc_time_t rtcTime; //rtc时间
st_rtc_time_t localTime; //local时间
static rt_device_t device;
//读取设备当前时间
device = rt_device_find(RTC_DEVICE_NAME);
if (device != RT_NULL)
{
rt_device_open(device, RT_DEVICE_FLAG_RDWR);
memzero(&rtcTime, sizeof(rtcTime));
rt_device_control(device, RTC_IOCTL_GET_TIME, &rtcTime);
memzero(&localTime, sizeof(localTime));
RTC_GetLocalTime(&localTime, &rtcTime);
rt_device_close(device);
}
//将当前时间赋值给awtk内部时间管理,
dt->year = localTime.year;
dt->month = localTime.month;
dt->day = localTime.day;
dt->hour = localTime.hour;
dt->minute = localTime.minute;
dt->second = localTime.second;
dt->wday = date_time_get_wday(dt->year, dt->month, dt->day); //此处需要自己计算星期时间
return RET_OK;
}
static ret_t date_time_set_now_impl(date_time_t* dt)
{
//此处添加在界面设置的新时间,即ATWK的日期时间,更新到单片机stm32上的时间
return RET_OK;
}
static ret_t date_time_from_time_impl(date_time_t* dt, uint64_t timeval) {
//此处获取单片机stm32上的时间,让其能更新到awtk内部时间
return RET_OK;
}
static uint64_t date_time_to_time_impl(date_time_t* dt) {
//此处添加在界面设置的新时间,即ATWK的日期时间,更新到单片机stm32上的时间
return 1;
}
//设置日期和时间的相关函数的实现
static const date_time_vtable_t s_date_time_vtable = {
date_time_get_now_impl,
date_time_set_now_impl,
date_time_from_time_impl,
date_time_to_time_impl,
};
成功!LCD屏上的时间控件不再是00 00 了。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)