1. 基于时间片的轮询调度算法(仅局限单核CPU芯片):

利用定时器为每个任务函数设定执行时间间隔,保证使用频率高的函数多次被调用,提高单核芯片的资源利用率。如果只是简单地将A、B两个函数放在while中,那么在一定时间内这两个函数调用的次数是一致的,,这样就浪费了单核芯片的资源。

2. 例子:

函数A(100μs执行一次----使用频率高),
函数B(1000μs执行一次----使用频率低)。
那么在1ms 内 函数A 执行了10次,而函数B只执行1次
当然你要保证函数A在100μs内执行完毕、函数B在1000μs内执行完毕
如果超出时间的话系统会变得卡顿。有部分的函数可能没有别执行到。毕竟单核芯片只在很短时间内只做一件事。

3. PS

1、从微观上单核芯片在某一个和短时间时间段只执行一件事。从宏观上 (比如:1S):单核芯片执行多件事情;
2、任务函数最好不要出现delay等延时函数,不然整个系统变得卡顿。

4. 为了更好地理解上述描述,可以结合以下代码理解(基于STM32F103C8T6芯片编写)

  1. API_Schedule.c
#include "API_Schedule.h"
#include "stdlib.h"/************任务初始化,每一个结构体都代表一个任务,添加任务和删减任务都在这里完成************/
struct TaskStruct TaskST[]=
{//  计时   多少ms调用一次    任务运行标志位    任务函数指针{ 0,       5000,              0,           LedFlash},{ 0,       1000,              0,           UARTFC},{ 0,        500,              0,           UserTestMode},
};/*******************************搭建时间片轮询机制代码框架********************************///记录任务数量
u8 TaskCount=  sizeof(TaskST)/sizeof(TaskST[0]);   //放在“TIM2_IRQHandler”中断执行,用于任务计时
void OS_IT_RUN(void)
{u8 i;for(i=0;i<TaskCount;i++)//遍历所有循环{   if(!TaskST[i].TaskStatus){      if(++TaskST[i].TaskTickNow >= TaskST[i].TaskTickMax)//计时,并判断是否到达定时时间{  TaskST[i].TaskTickNow = 0;TaskST[i].TaskStatus = 1;}}}
}//放在main函数中执行,自带死循环,用于执行挂起的任务
void PeachOSRun(void)
{u8 j=0;while(1){if(TaskST[j].TaskStatus)//判断一个任务是否被挂起{        TaskST[j].FC();             //执行该任务函数TaskST[j].TaskStatus=0;       //取消任务的挂起状态}if(++j>=TaskCount)//相当于不断循环遍历所有的任务j=0;       }
}/*************************计划表中的任务*****************************/
void LedFlash(void)
{//printf("Led \n");//调试用,需要自己添加uart外设后再使用这段代码
}void UARTFC(void)
{//printf("UARTFC \n");//调试用
}void UserTestMode(void)
{//printf("UserTestMode \n");//调试用
}
  1. API_Schedule.h
#ifndef __API_SCHEDULE_H__
#define __API_SCHEDULE_H__
#include "stm32f10x.h"//框架运行所需的函数声明
void PeachOSRun(void);
void OS_IT_RUN(void);/*
用与存储一个任务运行的数据
*/
struct TaskStruct
{u16    TaskTickNow;//用于计时u16   TaskTickMax;//设置计时时间u8  TaskStatus;//任务运行标志位void (*FC)();//任务函数指针
};extern struct TaskStruct TaskST[];    //声明为结构体数据,那样多个任务时方便管理//用于示例的任务函数声明
void LedFlash(void);
void UARTFC(void);
void UserTestMode(void);
#endif
  1. bsp_time.c
#include "bsp_time.h" //中断初始化
void Time2_NVIC_Init()
{NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel                       = TIM2_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority  = 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority         = 2;NVIC_InitStruct.NVIC_IRQChannelCmd                 = ENABLE;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);NVIC_Init(&NVIC_InitStruct);
}//定时器初始化
void Time2_Init(u16 arr,u16 psr)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_TimeBaseInitStruct.TIM_ClockDivision            =  0;TIM_TimeBaseInitStruct.TIM_CounterMode                =  TIM_CounterMode_Up;TIM_TimeBaseInitStruct.TIM_Period                    =  arr;TIM_TimeBaseInitStruct.TIM_Prescaler                =  psr;TIM_TimeBaseInitStruct.TIM_RepetitionCounter        =  0;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);TIM_ITConfig(TIM2, TIM_IT_Update,ENABLE);TIM_Cmd(TIM2, ENABLE);Time2_NVIC_Init();
}//定时器中断
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET){OS_IT_RUN();TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}
  1. bsp_time.h
#ifndef __TIME_H
#define __TIME_H#include "stm32f10x.h"
#include "API_Schedule.h"void Time2_Init(u16 arr,u16 psr);#endif
  1. main.c
#include "stm32f10x.h"
#include "bsp_time.h"
#include "API_Schedule.h"int main(void)
{Time2_Init(71,1000);   PeachOSRun();
}

STM32基于时间片轮询机制相关推荐

  1. 【状态保持】Cache 基于SQL 数据库 的缓存依赖 轮询机制详解

    首先声明一下如果您还不了解什么是Cache(缓存)请您先搜一下有关信息然后再看这篇文章. 当数据库中的信息发生变化的时候,应用程序能够获取变化的通知是缓存依赖得以实现的基础.应用程序可以通过两种途径获 ...

  2. 时间片轮询+状态机实现裸机多任务

    时间片+状态机实现裸机伪多任务 注:上述伪多任务是按个人理解命名的,实际上在裸机中跑的还是单线程,只是效果看上去是多线程. 时间片轮询方式是把MCU的执行时间划分为一块一块的,然后根据自己的需求去分配 ...

  3. (原创)Linux设备轮询机制分析

    一. 设备轮询机制的基本思想 所谓的设备轮询机制实际上就是利用网卡驱动程序提供的NAPI机制加快网卡处理数据包的速度,因为在大流量的网络环境当中,标准的网卡中断加上逐层的数据拷贝和系统调用会占用大量的 ...

  4. MCDF中arbiter的轮询机制

    更新的MCDF的仲裁器采用的是Round Robin轮询的一个仲裁机制,简单来说就是最先被授权的通道在下一次仲裁中优先级会变为最低,这样可以保证每个通道都能够获得授权,而不是一个通道长时间连续的进行数 ...

  5. 适合单片机使用的一个短小精悍的时间片轮询系统

    随着单片机外设的日益丰富,以及RAM,ROM的增大.RTOS实时操作系统被越来越广泛的使用.实时操作系统对任务的实时性高效处理是毋容置疑的! 但是有更多的情况我们仅仅需要一个短小精悍的轮询系统,比如实 ...

  6. 码支付如何对接网站_第四方聚合支付特色之一的轮询机制是怎么防风控的?

    简单地说,聚合支付是融合了支付宝.微信支付.花呗.翼支付等多种支付方式的一种"包容性"支付工具.做支付系统一定不能脱离实际业务场景,更不能照搬其他公司方案. 做聚合支付的服务商越来 ...

  7. android全局轮询机制,Android轮询机制

    在消息的获取上是选择轮询还是推送得根据实际的业务需要来技术选型,例如对消息实时性比较高的需求,比如微博新通知或新闻等那就最好是用推送了.但如果只是一般的消息检测比如更新检查,可能是半个小时或一个小时一 ...

  8. Node中的事件轮询机制

    文章目录 2 node中的事件循环模型 2-1 一些属性 2-2 循环模型 node事件循环总共有==六个阶段== process.nextTick()函数 __实例__ 2 node中的事件循环模型 ...

  9. 轮询机制php,JS事件轮询机制讲解

    JS是单线程语言,深入理解JS里的Event Loop,本文主要和大家分享JS事件轮询机制,希望能帮助到大家. JS的执行机制(一): 1.首先判断JS是同步还是异步,同步就进入主进程,异步就进入ev ...

最新文章

  1. 我眼中的DevOps(转)
  2. iOS_25彩票_幸运转盘
  3. 求助:如何在Vista系统环境下增加系统盘C盘的容量?
  4. Linux内核链表实现剖析
  5. Kotlin极简教程:第10章 Kotlin与Java互操作
  6. linux 产生0~100内的随机数
  7. MyBatis传入参数为List对象
  8. 【HDU - 1024 】Max Sum Plus Plus (dp及优化,最大m子段和)
  9. vs2010中自动缩进模式由tab改为space
  10. 一种动态组装SQL语句的方法
  11. bzoj 4337 树的同构
  12. Mysql BLOB和TEXT类型
  13. 学生激活windows,Visio等软件的正确姿势
  14. 定性分析 or 定量分析
  15. app打开QQ与陌生人聊天
  16. ⅰcp经济模型_简单介绍一下R中的几种统计分布及常用模型
  17. vue页面跳转打开新的窗口
  18. 这么优秀的Excel工具类,你难道不用?
  19. 当Sklearn遇上Plotly,机器学习变得如此简单、易于理解
  20. 基于高德SDK实现跑步时轨迹渐变功能

热门文章

  1. 串口打印问题,各位大侠帮帮忙!
  2. ESP32分区方案-arduino
  3. 多智能体系统——具有非线性不确定干扰的多智能体系统的固定时间事件触发一致性控制(附论文链接+源码Matlab)
  4. 用Linux命令行获取本机外网IP地址
  5. 华为交换机MAC地址表以及命令配置
  6. 如何正确规范写接口文档
  7. nmtui 和 nmcli 命令 配置网络
  8. anaconda,sublime使用
  9. android_Quantity Strings (Plurals)
  10. Linux三剑客详解带实验