STM32
直播中

摩托罗拉

8年用户 845经验值
私信 关注
[问答]

怎样利用时间片轮转调度算法去实现同步时间调度的程序呢

怎样利用时间片轮转调度算法去实现同步时间调度的程序呢?

回帖(1)

樊周依

2021-12-20 10:05:02
MDK编译测试 (分别在STM32F107和STM32F103芯片测试,分别调用了自带的库)
  

  这是个帮助实现同步时间调度的程序,需要低层硬件的支持(定时器中断)。它本身利用定时器(TIM4),使一个特殊的变量“SliceTime”从0开始随时间增长(1/ms),一旦达到了指定的最大值,又回归到零,如此往复……任何一段循环的程序可以通过SLICE宏来间接检查自己是否在允许的时间片内,如果此时不被允许执行,就跳过这段程序。这段源代码的意义就在于实现简单实用的同步时间调度。异步任务可能引起“竞争条件”等一些复杂的问题,如果只需要一个简单的方案就可以解决问题,那么同步编程仍然是最好的选择,这时如果再需要一个简单算法来调度若干个密集型同步任务,那么这段源代码正好可以派上用场!
  

  C用例:
    PS.这样的算法应该算是时间片轮转调度算法的一个变化形式,“时间片”在一些文献中用“quantum”这个词来表示,这里则用了“slice”,不过概念上也不完全相同。

#include "test.h"
#include "slice.h"
void Wireless(void);
void FetchData(void);
struct sensordata{
        short accx,accy,accz;
}SG;
                                                                                                                               
int main(void)
{                       
        Sys_Init();
        SliceTimer_Init(500);
        while(1){
                FetchData();
                Wireless();
        }                             
}

void Wireless(void){
        u8 tmp_buf[33];
        SLICE(1,300){
                LED1=0;
                TX_Mode();
                sprintf((char*)tmp_buf,"%d,%d,%d",(int)SG.accx,(int)SG.accy,(int)SG.accz);
                if(NRF24L01_TxPacket(tmp_buf)==0);
                LED1=1;
        }
        SLICE(301,500){
                LED0=0;
                RX_Mode();
                if(NRF24L01_RxPacket(tmp_buf)==0)
                {
                tmp_buf[32]=0;
                LCD_ShowString(60,170,tmp_buf);
                }
                LED0=1;
        }
}

void FetchData(void){
        static unsigned int giveups;
        if(giveups>1000){
                ADXL345_Read(&SG.accx,&SG.accy,&SG.accz);
                LCD_ShowInt(92,70,SG.accx,6,16);
                LCD_ShowInt(92,90,SG.accy,6,16);
                LCD_ShowInt(92,110,SG.accz,6,16);
                giveups=0;
        }
        else giveups++;
}

Slice.h

#ifndef __SLICE_H_
#define __SLICE_H_
#define SLICE(__s,__e)         if(SliceTime>=(__s)&&SliceTime<=(__e))
extern volatile unsigned int SliceTime;
extern unsigned int SliceTimeMax;
void SliceTimer_Init(unsigned int smax);
#endif

Slice.c

  

#include "slice.h"
#include
volatile unsigned int SliceTime; //ms
unsigned int SliceTimeMax;
void SliceTimer_Init(unsigned int smax){
        NVIC_InitTypeDef NVIC_InitStructure;
        RCC->APB1ENR|=1<<2; //TIM4时钟使能   
        TIM4->ARR=10;//设定计数器自动重装值 10/10kHz=1ms
        TIM4->PSC=7199;//预分频器7200
        TIM4->DIER|=1<<0;   //允许更新中断                               
        TIM4->DIER|=1<<6;   //允许触发中断                                                                      
        TIM4->CR1=0x8000;//ARPE使能
        TIM4->CR1|=0x01;    //使能定时器4
          NVIC_InitStructure.NVIC_IRQChannel = 30; //TIM4_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
          SliceTime=0;       
          SliceTimeMax=smax;          
}

void TIM4_IRQHandler(void)
{                                                                   
        if(TIM4->SR&0X0001){
                SliceTime++;
                if(SliceTime>SliceTimeMax)SliceTime=0;
        }                                                                                                                                                          
        TIM4->SR&=~(1<<0);//清除中断标志位             
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分