软件定时器基本概念
- 软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器,当经过设定的Tick时钟计数值后会触发用户定义的回调函数。定时精度与系统Tick时钟的周期有关。硬件定时器受硬件的限制,数量上不足以满足用户的实际需求,因此为了满足用户需求,提供更多的定时器,LiteOS操作系统提供软件定时器功能。软件定时器扩展了定时器的数量,允许创建更多的定时业务。
- 软件定时器功能上支持: ⚫ 静态裁剪:能通过宏关闭软件定时器功能。 ⚫ 软件定时器创建。 ⚫ 软件定时器启动。 ⚫ 软件定时器停止。 ⚫ 软件定时器删除。 ⚫ 软件定时器剩余Tick数获取。
软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则,先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先被触发的准则。软件定时器以Tick为基本计时单位,当用户创建并启动一个软件定时器时,Huawei LiteOS会根据当前系统Tick时间及用户设置的定时间隔确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,看是否有定时器超时,若有则将超时的定时器记录下来。Tick中断处理函数结束后,软件定时器任务(优先级为最高)被唤醒,在该任务中调用之前记录下来的定时器的超时回调函数。
实现软件定时器创建- cmsis_os2的API软件定时器接口简介:
- 创建定时器:osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr);
- 启动定时器:osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks);
- 停止定时器:osStatus_t osTimerStop (osTimerId_t timer_id);
- 删除定时器:osStatus_t osTimerDelete (osTimerId_t timer_id);
#include
#include
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
osStatus_t timer1_status;
osStatus_t timer2_status;
void timer1_handler(void *p)
{
char *str = p;
printf("timer1_handler %s\r\n",str);
}
void timer2_handler(void *p)
{
uint32_t *cnt = p;
printf("timer2 handler %d\r\n",*cnt);
(*cnt)++;
if(*cnt & 0x01)
{
GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_VALUE1);
}
else
{
GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_VALUE0);
}
}
void my_led_example(void)
{
GpioInit();
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_DIR_OUT);
osTimerId_t id = osTimerNew(timer1_handler,osTimerOnce,"timer1",NULL);
if(id != NULL)
{
timer1_status = osTimerStart(id,100); // 1s
if(timer1_status != osOK)
{
printf("Timer 1 could not be started\r\n");
}
}
static uint32_t cnt = 10;
id = osTimerNew(timer2_handler,osTimerPeriodic,&cnt,NULL);
if(id != NULL)
{
timer2_status = osTimerStart(id,50);
if(timer2_status != osOK)
{
printf("Timer 2 could not be started\r\n");
}
}
}
SYS_RUN(my_led_example);
- 编译烧录运行,timer1为单次,运行一次打印了timer1字符串,timer2为500毫秒周期性定时器,打印计数递增值,且LED在交替亮灭
- LED闪烁效果
#include
#include
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
osStatus_t timer1_status;
void timer1_handler(void *p)
{
uint32_t *cnt = p;
printf("timer1_handler %d\r\n",*cnt);
}
void my_led_example(void)
{
GpioInit();
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_DIR_OUT);
uint32_t cnt = 1;
osTimerId_t id = osTimerNew(timer1_handler,osTimerOnce,&cnt,NULL);
if(id != NULL)
{
timer1_status = osTimerStart(id,100); // 1s
if(timer1_status != osOK)
{
printf("Timer 1 could not be started\r\n\r\n");
}
else
{
printf("Timer 1 could be started\r\n\r\n");
}
}
osDelay(50);
timer1_status = osTimerStop(id);
if(timer1_status != osOK)
{
printf("stop Timer1 failed\r\n\r\n");
}
else
{
printf("stop Timer1 success\r\n\r\n");
}
timer1_status = osTimerStart(id, 100);
if (timer1_status != osOK)
{
printf("start Timer1 failed\r\n\r\n");
}
else
{
printf("start Timer1 success\r\n\r\n");
}
osDelay(200U);
timer1_status = osTimerStop(id);
if(timer1_status != osOK)
{
printf("stop Timer1 failed\r\n\r\n");
}
else
{
printf("stop Timer1 success\r\n\r\n");
}
timer1_status = osTimerDelete(id);
if(timer1_status != osOK)
{
printf("delete Timer1 failed\r\n\r\n");
}
else
{
printf("delete Timer1 success\r\n\r\n");
}
}
SYS_RUN(my_led_example);
- 编译烧录运行