灵动微课堂 (第242讲)|使用MM32F3270基于Azure RTOS定时器组的应用
来源:灵动MM32MCU 发布时间:2022-12-29 分享至微信

简 介

Azure RTOS ThreadX 是 Microsoft 提供的高级工业级实时操作系统 (RTOS)。它是专门为深度嵌入式实时 IoT 应用程序设计的。Azure RTOS ThreadX 提供高级计划、通信、同步、计时器、内存管理和中断管理功能。此外,Azure RTOS ThreadX 具有许多高级功能,包括 picokernel™ 体系结构、preemption-threshold™ 计划、event-chaining™、执行分析、性能指标和系统事件跟踪。Azure RTOS ThreadX 非常易于使用,适用于要求极其苛刻的嵌入式应用程序。Azure RTOS ThreadX 在各种产品(包括消费者设备、医疗电子设备和工业控制设备)上的部署次数已达数十亿次。

具体的介绍和用户指南可以参考:

https://docs.microsoft.com/zh-cn/azure/rtos/threadx/

在前文描述移植基本内核的基础上,该应用手册描述了MM32F3270系列MCU结合Azure RTOS ThreadX定时器组的使用,引导用户理解Azure RTOS ThreadX应用程序计时器功能。

表 1 适用系列型号

系列

芯片型号

开发板

MM32F3270

MM32F3273G9P

EVB-F3270


1

移植应用的准备

1.1 硬件开发板的准备

该移植过程中应用的开发板为MM32的EVB-F3270,板载MM32F3273G9P。

EVB-F3270 (MM32F3273G9P) 的简要参数:

Arm Cortex-M3 内核

板载 MM32F3273G9P(LQFP144)

USB Host / Device、SPI、I2C

4 x Key、4 x LED

I2S Speaker

TF-Card

Ethernet PHY


1.2 软件的准备

库函数和例程(Lib Samples)

该移植过程中应用的 Firmware 分别为 MM32F3270 库函数和例程,下载地址:

https://www.mindmotion.com.cn/products/mm32mcu/mm32f/mm32f_mainstream/mm32f3270/

Azure RTOS ThreadX(源码)

ThreadX 的源代码已经开放,我们可以从 ThreadX 公共源代码存储库获取 Azure RTOS ThreadX,网址为:

https://github.com/azure-rtos/threadx/

具体的商用使用条件参考Azure的许可证说明:

https://www.microsoft.com/en-us/legal/intellectualproperty/tech-licensing/programs?msclkid=f7ab4ff3afa011ec90a79366a52034faactivetab=pivot1:primaryr11

Microsoft publishes the Azure RTOS source code to GitHub. No license is required to install and use the software for internal development, testing, and evaluation purposes. A license is required to distribute or sell components and devices unless using Azure RTOS licensed hardware.

Azure RTOS 何时需要许可证?

Microsoft 将 Azure RTOS 源代码发布到 GitHub。安装和使用该软件进行内部开发、测试和评估无需许可证。分发或销售组件和设备需要许可证,除非使用 Azure RTOS 许可的硬件。

ThreadX 安装

可以通过将 GitHub 存储库克隆到本地计算机来安装 ThreadX。下面是用于在 PC 上创建 ThreadX 存储库的克隆的典型语法。

shell复制

git clone https://github.com/azure-rtos/threadx

或者,也可以使用 GitHub 主页上的“下载”按钮来下载存储库的副本。

下载后的仓库代码目录列表如下:

Azure RTOS ThreadX(源码)支持的开发环境

ThreadX 内核提供好了各种主流硬件平台和软件平台的移植文件,以Cortex_M3为例,可以支持以下六种开发环境:

本次移植过程使用Azure RTOS原有的sample_threadx.c文件为例,稍作修改,演示定时器组功能。

2

ThreadX定时器组的应用

该章节介绍动态内存管理相关知识,演示程序可在MM32F3273G9P的EVB-F3270上运行。此示例在文件 main_timer_demo.c 中实现,旨在说明如何在嵌入式多线程环境中使用定时器组功能。

2.1 定时器组

2.1.1 应用程序计时器

快速响应异步外部事件是嵌入式实时应用程序中最重要的功能。但是,其中的许多应用程序还必须按预定的时间间隔执行某些活动。

借助 ThreadX 应用程序计时器,应用程序能够按特定的时间间隔执行应用程序 C 函数。应用程序计时器也可能只过期一次。这种类型的计时器称为“单次计时器”,而重复间隔计时器称为“定期计时器”。

每个应用程序计时器都是一个公用资源。ThreadX 对如何使用应用程序计时器没有任何限制。

2.1.2 计时器间隔

在 ThreadX 中,时间间隔通过定期计时器中断来测量。每个计时器中断称为计时器时钟周期。计时器时钟周期之间的实际时间由应用程序指定,但 10 毫秒是大多数实现的标准时间。定期计时器设置通常位于 tx_initialize_low_level 程序集文件中。

值得一提的是,基础硬件必须能够生成定期中断,应用程序计时器才会正常运行。在某些情况下,处理器具有内置的定期中断功能。如果处理器没有此功能,用户的主板必须包含可生成定期中断的外围设备。

即使没有定期中断源,ThreadX 仍可正常工作。但随后会禁用所有与计时器相关的处理。这包括时间切片、挂起超时和计时器服务。

2.1.3 计时器准确性

计时器过期时间根据时钟周期指定。达到每个计时器时钟周期时,指定到期值将减一。由于应用程序计时器可在计时器中断(或计时器时钟周期)之前启用,因此,实际过期时间可能会提前一个时钟周期。

如果计时器时钟周期速率为 10 毫秒,应用程序计时器可能会提前 10 毫秒过期。与 1 秒计时器相比,这对 10 毫秒计时器更重要。当然,增加计时器中断频率会减少此误差范围。

2.1.4 计时器执行

应用程序计时器按照其激活的顺序执行。例如,如果创建了三个具有相同过期值的计时器并已激活,这些计时器对应的过期函数将保证按它们激活的顺序执行。

2.1.5 创建应用程序计时器

应用程序计时器由应用程序线程在初始化期间或运行时创建。应用程序中应用程序计时器的数量没有限制。

2.1.6 运行时应用程序计时器性能信息

ThreadX 提供可选的运行时应用程序计时器性能信息。如果 ThreadX 库和应用程序是在定义 TX_TIMER_ENABLE_PERFORMANCE_INFO 的情况下生成的,ThreadX 会累积以下信息。

整个系统的总数:

激活数

停用数

重新激活(定期计时器)

expirations

过期调整数

每个应用程序计时器的总数:

激活数

停用数

重新激活(定期计时器)

expirations

过期调整数

此信息在运行时通过 tx_timer_performance_info_get 和 tx_timer_performance_system_info_get 服务提供。应用程序计时器性能信息在确定应用程序是否正常运行时非常有用。此信息对于优化应用程序也很有用。

2.1.7 应用程序计时器控制块 TX_TIMER

每个应用程序计时器的特征都可在其控制块中找到。该控制块包含诸如 32 位过期标识值等有用信息。此结构在 tx_api.h 文件中定义。

应用程序计时器控制块可以位于内存中的任意位置,但最常见的是通过在任何函数的作用域外部定义该控件块来使其成为全局结构。

2.1.8 计时器过多

默认情况下,应用程序计时器在优先级为 0 时运行的隐藏系统线程中执行,该线程的优先级通常比任何应用程序线程都高。因此,在应用程序计时器内进行处理应保持最小值。

如果可能,还应尽可能避免使用在每个时钟周期过期的计时器。这种情况可能导致应用程序的开销过大。

如前所述,应用程序计时器在隐藏的系统线程中执行。因此,请不要在应用程序计时器的过期函数内执行任何 ThreadX 服务调用时选择挂起。

2.1.9 相对时间

除了前面所述的应用程序计时器,ThreadX 还提供单个连续递增的 32 位时钟周期计数器。每次发生计时器中断时,时钟周期计数器或时间就会加一。

应用程序可以通过分别调用 tx_time_get 和 tx_time_set 来读取或设置此 32 位计数器。此时钟周期计数器的使用完全由应用程序确定。ThreadX 不在内部使用此计时器。

2.2 Azure ThreadX 定时器组的相关函数

tx_timer_create 创建应用程序计时器

UINTtx_timer_create(
TX_TIMER*timer_ptr,
CHAR*name_ptr,
VOID(*expiration_function)(ULONG),
ULONGexpiration_input,
ULONGinitial_ticks,
ULONGreschedule_ticks,
UINTauto_activate);


说明

此服务创建具有指定过期函数和定期的应用程序计时器。

参数

timer_ptr:

指向计时器控制块的指针。

name_ptr:

指向计时器名称的指针。

expiration_function:

在计时器过期时要调用的应用程序函数。

expiration_input:

在计时器过期时要传递到过期函数的输入。

initial_ticks:

指定计时器过期的初始时钟周期数。合法值的范围为 1 至 0xFFFFFFFF。

reschedule_ticks:

指定第一个计时器过期后所有计时器过期的时钟周期数。如果此参数为 0,则计时器是一次性的。否则,对于周期性计时器,合法值的范围为 1 至 0xFFFFFFFF。

备注

一次性计时器过期后,必须通过 tx_timer_change 将其重置,然后才能再次激活。

auto_activate:

确定创建期间是否自动激活计时器。如果此值为 TX_AUTO_ACTIVATE (0x01),则激活计时器。否则,如果选择了值 TX_NO_ACTIVATE (0x00),则所创建的计时器处于非活动状态。在这种情况下,随后需要调用 tx_timer_activate 服务来实际启动计时器。

返回值

TX_SUCCESS:

(0X00) 成功创建应用程序计时器。

TX_TIMER_ERROR:

(0X15) 应用程序计时器指针无效。指针为 NULL 或已创建计时器。

TX_TICK_ERROR:

(0x16) 为初始时钟周期提供的值无效(零)。

TX_ACTIVATE_ERROR:

(0x17) 选择的激活无效。

NX_CALLER_ERROR:

(0x13) 此服务的调用方无效。

示例

TX_TIMERmy_timer;
UINTstatus;

/*Createanapplicationtimerthatexecutes
"my_timer_function"after100ticksinitiallyandthen
afterevery25ticks.Thistimerisspecifiedtostart
immediately!*/
status=tx_timer_create(my_timer,"my_timer_name",
my_timer_function,0x1234,100,25,
TX_AUTO_ACTIVATE);

/*IfstatusequalsTX_SUCCESS,my_timer_functionwill
becalled100timertickslaterandthencalledevery
25timerticks.Notethatthevalue0x1234ispassedto
my_timer_functioneverytimeitiscalled.*/


另请参阅

tx_timer_activate

tx_timer_change

tx_timer_deactivate

tx_timer_delete

tx_timer_info_get

tx_timer_performance_info_get

tx_timer_performance_system_info_get

具体函数的中文说明可以参考:

https://docs.microsoft.com/zh-cn/azure/rtos/threadx/chapter4

具体函数的英文说明可以参考:

https://docs.microsoft.com/en-us/azure/rtos/threadx/threadx-smp/chapter4

2.3 定时器组的应用演示

2.3.1 工程目录的建立

打开目标工程文件夹“MM32F3270Project”:

移除原有样例.c 文件sample_threadx.c:

参考sample_threadx.c建立main_timer_demo.c文件,并添加hardware目录中的led.c、key.c到工程项目中。


3

ThreadX的定时器组应用

3.1 代码实现

下载调试默认会运行到main()函数,如下为全部实现的代码。

Demo演示代码

/*Thisisasmalldemoofthehigh-performanceThreadXkernel.Itincludesexamplesofsix
threadsofdifferentpriorities,usingamessagequeue,semaphore,andaneventflagsgroup.*/


#include"tx_api.h"
#include"delay.h"
#include"led.h"
#include"key.h"
#include"uart.h"

#defineDEMO_STACK_SIZE1024

#defineTHREAD0_PRIORITY1
#defineTHREAD0_PREEMPTION_THRESHOLD1


/*DefinetheThreadXobjectcontrolblocks...*/
TX_THREADthread_0;

TX_TIMERMyTimer;

/*Definethecountersusedinthedemoapplication...*/
ULONGthread_0_counter;

/*Definethethreadstacks.*/
UCHARthread_0_stack[DEMO_STACK_SIZE];

/*Definethreadprototypes.*/

voidthread_0_entry(ULONGthread_input);


volatileunsignedintbootloop;


voidSystem_Init(void);
voidAppThreadCreate(void);
voidAppModuleCreate(void);


/*Definemainentrypoint.*/

intmain()
{
System_Init();

/*EntertheThreadXkernel.*/
tx_kernel_enter();
}


/*Definewhattheinitialsystemlookslike.*/

voidtx_application_define(void*first_unused_memory)
{
AppThreadCreate();
AppModuleCreate();

}

voidSystem_Init(void)
{
DELAY_Init();//cannotusesystick
LED_Init();
KEY_Init();
CONSOLE_Init(115200);
printf("!!!Start!!!\r\n");

}

voidAppThreadCreate(void)
{
/*Createthread0.*/
tx_thread_create(
thread_0,
"thread0",
thread_0_entry,
0,
thread_0_stack,
DEMO_STACK_SIZE,
THREAD0_PRIORITY,
THREAD0_PREEMPTION_THRESHOLD,
TX_NO_TIME_SLICE,
TX_AUTO_START);

}

voidAppModuleCreate(void)
{
/*Createatimergroup.*/
tx_timer_create(MyTimer,
"MyTimer",
TimerCallback,
0,/*Theparameterspassed*/
100,/*Settheinitialdelayfortimertimeoverflow*/
1000,/*Setthetimerrunperiodaftertheinitialdelay*/
TX_AUTO_ACTIVATE);/*Activatethetimer*/
}


/*Thecallbackfunctionforthetimergroup.*/
voidTimerCallback(ULONGthread_input)
{

LED2_TOGGLE();

}

/*Definethetestthreads.*/
voidthread_0_entry(ULONGthread_input)
{
/*ThisthreadsimplycontrolsLEDflashingtoindicatethatthesystemisrunning*/
while(1)
{
/*Incrementthethreadcounter.*/
thread_0_counter++;
LED1_TOGGLE();
/*Sleepfor300ticks.*/
tx_thread_sleep(300);

}
}


3.2 下载与调试

运行程序,板载LED1闪烁,表示当前系统正在运行。

观察LED2间隔1s闪烁。

程序中创建定时器组,设置溢出周期为1000ms,在定时器回调函数中配置LED2引脚翻转,激活定时器。当计时周期到时,LED2引脚翻转,运行现象是LED2间隔1s闪烁,Demo演示成功。


4

小结

Azure RTOS ThreadX提供定时器组能够使应用程序按照特定的时间间隔执行,结合MM32F3270的强大性能,可以实现Azure RTOS广泛的应用场景。


往期精彩

第241讲|使用MM32F3270基于Azure RTOS动态内存管理的应用

第240讲|使用MM32F3270基于Azure RTOS信号量的应用

第239讲|MM32F5270 TIM 精准脉冲数量输出

第238讲|MM32F5270定时器单脉冲输出

第237讲|基于MM32L0130的LPUART应用(2)

第236讲|基于MM32L0130的LPUART应用(1)

第235讲 | MM32L013x——LPTIM的应用介绍

第234讲 | 基于MM32L0130的低功耗电子时钟设计

第233讲 | MM32L0130 RTC 日历和闹钟

第232讲 | 使用MM32L0130 SLCD驱动LCD显示

第231讲 | 使用MM32L0130 IRM实现红外发码

第230讲 | 基于MM32F5270的I2S音频播放

第229讲 | 基于MM32F0140的UDS Bootloader学习笔记

第228讲 | MM32F5 硬件系统设计

第227讲 | 基于F0040串口实现AT指令解析

第226讲 | 灵动微控制器软件开发平台MindSDK简介

第225讲 | MM32F0140学习笔记——CRC

第224讲 | MM32F0140 FlexCAN一致性测试 (2)

第223讲 | MM32F0140 FlexCAN一致性测试 (1)

第222讲 | MM32F0140学习笔记——独立看门狗(IWDG)

第221讲 | 使用MM32F3270基于Azure RTOS抢占任务的应用

第220讲 | 使用MM32F3270基于Azure RTOS事件标志组的应用

第219讲 | 使用MM32F3270基于Azure RTOS消息队列的应用

第218讲 | 使用MM32F3270基于Azure RTOS (ThreadX)的多任务调度

第217讲 | 使用MM32F3270基于Azure RTOS (ThreadX) 的移植

第216讲 | MM32F0140学习笔记——ADC

第215讲 | MM32F0140学习笔记——窗口看门狗(WWDG)

第214讲 | MM32F0140学习笔记——I2C

第213讲 | MM32F0140学习笔记——FlexCAN 控制器局域网

第212讲 | 工程师笔记——MM32F0040使用总结 (2)

第211讲 | 工程师笔记——MM32F0040使用总结 (1)

第210讲 | 工程师笔记——MM32F0020使用总结

第209讲 | 工程师笔记——MM32F0010使用总结

第208讲 | MM32F0140学习笔记——TIM

第207讲 | MM32F0140学习笔记——时钟系统RCC

第206讲 | MM32F0140学习笔记——COMP

第205讲 | MM32F0140学习笔记——SPI

第204讲 | MM32F0140学习笔记——DMA

第203讲 | MM32F0140学习笔记——UART

第202讲 | MM32F0140学习笔记——EXTI

第201讲 | MM32F0140学习笔记——GPIO

第200讲 | 使用MM32F0270 定时器DMA方式输出PWM

灵动微课堂大合辑


关于灵动

上海灵动微电子股份有限公司成立于 2011 年,是中国本土领先的通用 32 位 MCU 产品及解决方案供应商。公司基于 Arm Cortex-M 系列内核开发的 MM32 MCU 产品拥有 F/L/A/SPIN/W 五大系列,目前已量产 200多款型号,累计交付超 4 亿颗,每年都有近亿台配备了灵动 MM32MCU 的优秀产品交付到客户手中,在本土通用 32 位 MCU 公司中位居前列。

灵动客户涵盖智能工业、汽车电子、通信基建、医疗健康、智慧家电、物联网、个人设备、手机和电脑等应用领域。灵动是中国为数不多的同时获得了 Arm-KEIL、IAR、SEGGER 官方支持的本土 MCU 公司,并建立了独立、完整的通用 MCU 生态体系。灵动始终秉承着“诚信、承诺、创新、合作”的精神,为客户提供从硬件芯片到软件算法、从参考方案到系统设计的全方位支持。


灵动股份

微信号:MindMotion-MMCU

长按识别二维码关注我们

MORE

官网:www.mm32mcu.com

微信公众号:灵动MM32MCU

灵动MM32MCU技术论坛:

bbs.21ic.com/iclist-696-1.html

[ 新闻来源:灵动MM32MCU,更多精彩资讯请下载icspec App。如对本稿件有异议,请联系微信客服specltkj]
存入云盘 收藏
举报
全部评论

暂无评论哦,快来评论一下吧!