单片机裸机开发框架

本文介绍了嵌入式系统中常见的四种任务调度方式:轮询、基于中断的前后台、定时器驱动的前后台以及时间片调度。时间片调度通过精确的时间分配确保了任务的及时执行,避免了高耗时函数导致的任务延误问题,是推荐的实现方式。
摘要由CSDN通过智能技术生成

前言

单片机逻辑开发框架,轮询,前后台,利用定时器的前后台


提示:以下是本篇文章正文内容,下面案例可供参考

一、轮询

该方法比较简单,在main函数内执行while(1),在while内顺序执行函数

void main(void)
{
    //外设初始化
    xx_Init();
    

    while(1)
    {
        a();
        b();
        c();
    }

}

二、前后台

中断为后台,在中断内更新全局变量,利用全局变量判断要更新那个函数

代码如下(示例):

volatile BOOL bFlag;//volatile 修饰变量,执行时直接从内存获取变量值
void xxx_IRQHandler(void)
{
    bFlag = true;
}

void xxx_IRQHandler(void)
{
    bFlag = true;
}

void main(void)
{
    //外设初始化
    xx_Init();
    
    while(1)
    {
        if(true == bFlag)
        {
            bFlag = false;
            a();
        }        
    }

}

三、利用定时器的前后台系统

定时器可以为普通定时器,也可以为滴答定时器

函数周期运行的方法可以为定时器中断函数内对全局变量a计数,在主循环内获取计数值,根据a的值,计算出决定执行哪些函数

volatile unsigned short a = 0;
void TIME1_IRQHandler()
{
    a++;
}

//假设定时器配置为1ms中断一次
void main(void)
{
    xxx_Init();//外设初始化
    
    //函数执行周期根据实际情况
    while(1)
    {
        if(0 == (a%2))
        {
            Fun_2ms();
        }

        if(0 == (a%4))
        {
            Fun_4ms();
        }
    }
}

四、时间片调度

第三种方式有缺陷(时间调度不一定准确,遇到执行时长高的函数会导致一些函数不能及时进行),推荐使用第四种方式。

/* 结构体 */
typedef struct __TIME_SLICE_SCHEDULING__
{
    void (*handler)(void);         /* 周期执行函数 */
    uint16_t timeout;               /* 超时时间 */
    uint16_t timer_cnt;             /* 时间片计数 */
    uint16_t run_times;             /* 最大运行次数,0为无限次 */
    uint16_t run_cnt;               /* 运行次数计数,无限次时不计数 */
    volatile uint16_t run_flag;     /* 运行标志,非零表示超时时间到达 */
}TIME_SLICE_SCHEDULING;
#define TIME_SLICE_SCHEDULING_TASKS 6 /* 假如有6组任务 */
TIME_SLICE_SCHEDULING g_time_slice_tasks[TIME_SLICE_SCHEDULING_TASKS];

/* 该函数放在滴答定时器内,实现时间片的时间基准。即对时间片的一些变量进行处理 */
void bsp_delay_base(void)
{
	uint8_t i;

	for ( i = 0; i < TIME_SLICE_SCHEDULING_TASKS; i++)
	{
		g_time_slice_tasks[i].timer_cnt++;
		if (g_time_slice_tasks[i].timer_cnt >= g_time_slice_tasks[i].timeout)
		{
			g_time_slice_tasks[i].timer_cnt = 0;
			g_time_slice_tasks[i].run_flag = 1;
		}
	}
}

/* main函数 */
void main(void)
{
    Init_xxx();
    while (1U)
    {
		for (task_index = 0; task_index < TIME_SLICE_SCHEDULING_TASKS; task_index++)
		{
			if (1 == g_time_slice_tasks[task_index].run_flag)
			{
				g_time_slice_tasks[task_index].run_flag = 0;
				g_time_slice_tasks[task_index].run_cnt++;
				if ((0 == g_time_slice_tasks[task_index].run_times)||(g_time_slice_tasks[task_index].run_cnt <= g_time_slice_tasks[task_index].run_times))
				{
					g_time_slice_tasks[task_index].run_cnt = g_time_slice_tasks[task_index].run_times + 1;
					if (g_time_slice_tasks[task_index].handler)
					{
						g_time_slice_tasks[task_index].handler();
					}
				}
			}
		}
    }
}

也可以参考GitHub - 0x1abin/MultiTimer: Software timers extend module for embedded


总结

无。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值