13

kings669669 · 2022年08月06日 · 江西

【MM32F5270开发板试用】SysTick+Scheduler轮询

【MM32F5270开发板试用】SysTick+Scheduler轮询

上一篇文章:【MM32F5270开发板试用】一、依靠SPI_SD,移植FatFs文件系统
本次所有代码按照以前习惯全部开源:我的Github地址是:https://github.com/kings669/M...
由于开发需要,人工加一个轮询系统,方便之后的开发。

一、SysTick配置

static uint64_t SysRunTimeMs = 0;
static uint8_t fac_us = 0;
static uint32_t fac_ms = 0;

void SysTick_Init(void)
{
        uint32_t reload = 0;

        SysTick->CTRL &= (uint32_t)0xFFFFFFFB;
        fac_us = CLOCK_SYS_FREQ / 8000000U;
        fac_ms = CLOCK_SYS_FREQ / 8000U;

        reload = CLOCK_SYSTICK_FREQ/1000;
        reload--;

        SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
        SysTick->LOAD = reload;
        SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
  SysRunTimeMs++;
}

uint32_t GetSysRunTimeMs(void)
{
    return SysRunTimeMs;
}

顺便写一个延时函数

void delay_us(uint16_t nus)
{
    uint32_t ticks = 0;
    uint32_t told = 0;
    uint32_t tnow = 0;
    uint32_t tcnt = 0;
    uint32_t reload = 0;
    reload = SysTick->LOAD;
    ticks = nus * fac_us;
    told = SysTick->VAL;
    while (1)
    {
        tnow = SysTick->VAL;
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += told - tnow;
            }
            else
            {
                tcnt += reload - tnow + told;
            }
            told = tnow;
            if (tcnt >= ticks)
            {
                break;
            }
        }
    }
}

void delay_ms(uint16_t nms)
{
    uint32_t ticks = 0;
    uint32_t told = 0;
    uint32_t tnow = 0;
    uint32_t tcnt = 0;
    uint32_t reload = 0;
    reload = SysTick->LOAD;
    ticks = nms * fac_ms;
    told = SysTick->VAL;
    while (1)
    {
        tnow = SysTick->VAL;
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += told - tnow;
            }
            else
            {
                tcnt += reload - tnow + told;
            }
            told = tnow;
            if (tcnt >= ticks)
            {
                break;
            }
        }
    }
}

二、轮询

轮询这里直接使用了匿名飞控的轮询。

#include "Scheduler.h"


static void Loop_1000Hz(void) 
{
    
}

static void Loop_500Hz(void) //2ms
{
    
}

static void Loop_200Hz(void) //5ms
{

}

static void Loop_100Hz(void) //10ms
{
    
}

static void Loop_50Hz(void) //20ms
{
    
}

static void Loop_20Hz(void) //50ms
{

}

static void Loop_2Hz(void) //500ms
{
    printf("Test 2Hz\r\n");
}

static sched_task_t sched_tasks[] =
    {
        {Loop_1000Hz, 1000, 0, 0},
        {Loop_500Hz, 500, 0, 0},
        {Loop_200Hz, 200, 0, 0},
        {Loop_100Hz, 100, 0, 0},
        {Loop_50Hz, 50, 0, 0},
        {Loop_20Hz, 20, 0, 0},
        {Loop_2Hz, 2, 0, 0},
};

#define TASK_NUM (sizeof(sched_tasks) / sizeof(sched_task_t))

void Scheduler_Setup(void)
{
    uint8_t index = 0;

    for (index = 0; index < TASK_NUM; index++)
    {

        sched_tasks[index].interval_ticks = TICK_PER_SECOND / sched_tasks[index].rate_hz;

        if (sched_tasks[index].interval_ticks < 1)
        {
            sched_tasks[index].interval_ticks = 1;
        }
    }
}

void Scheduler_Run(void)
{
    uint8_t index = 0;


    for (index = 0; index < TASK_NUM; index++)
    {

        uint32_t tnow = GetSysRunTimeMs();

        if (tnow - sched_tasks[index].last_run >= sched_tasks[index].interval_ticks)
        {
            sched_tasks[index].last_run = tnow;
            sched_tasks[index].task_func();
        }
    }
}

/******************* (C) COPYRIGHT 2014 ANO TECH *****END OF FILE************/

三、验证效果

可以看出效果还是很不错的
image.png

总结

要问我为什么不用RTOS,我已经尝试过,没有成功就作罢了。比如再移植RT-Thread的时候,有个文件不支持ARM6的编译器。移植FreeRTOS的时候,有几个地方一直报错,网上也没有相关的资料。对这个架构也不熟悉,为了项目进场,尝试一番过后,选中最简单的轮询。希望MindSDK可以快速跟进💪

推荐阅读
关注数
6151
内容数
276
灵动MM32 MCU相关技术知识,欢迎关注~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息