0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用MM32F3270基于Azure RTOS信号量的应用

灵动MM32MCU 来源:灵动MM32MCU 作者:灵动MM32MCU 2022-12-16 09:23 次阅读

简 介

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应用Counting Semaphores的使用,引导用户理解Azure RTOS ThreadX信号量功能。

表 1 适用系列型号

系列 芯片型号 开发板
MM32F3270 MM32F3273G9P EVB-F3270

1移植应用的准备

1.1 硬件开发板的准备

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

75f9efb2-7c69-11ed-8abf-dac502259ad0.png

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/

76b9b040-7c69-11ed-8abf-dac502259ad0.png    

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=f7ab4ff3afa011ec90a79366a52034fa&activetab=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 主页上的“下载”按钮来下载存储库的副本。

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

76dbacf4-7c69-11ed-8abf-dac502259ad0.png    

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

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

76fcd6c2-7c69-11ed-8abf-dac502259ad0.png

本次移植过程使用Azure RTOS原有的sample_threadx.c文件为例,稍作修改,演示信号量的功能与应用。

2Threadx 信号量的应用

该章节介绍信号量的相关知识,演示程序可在MM32F3273G9P的EVB-F3270上运行。

此示例在文件 main_semaphore_demo.c 中实现,旨在说明如何在嵌入式多线程环境中使用信号量,实现任务之间的同步和资源共享机制。

2.1 信号量

2.1.1 统计信号量

ThreadX 提供 32 位计数信号灯,其值范围在 0 到 4,294,967,295 之间。计数信号灯有两个操作:tx_semaphore_get 和 tx_semaphore_put 。执行获取操作会将信号灯数量减一,如果信号灯为 0,获取操作不会成功。获取操作的逆操作是放置操作,该操作会将信号灯数量加一。

每个计数信号灯都是一个公用资源,ThreadX 对如何使用计数信号灯没有任何限制。

计数信号灯通常用于互相排斥,也可将计数信号灯用作事件通知的方法。

2.1.2 互相排斥

互相排斥用于控制线程对某些应用程序区域(也称为关键部分或应用程序资源)的访问 。将信号灯用于互相排斥时,信号灯的“当前计数”表示允许访问的线程总数。在大多数情况下,用于互相排斥的计数信号灯的初始值为 1,这意味着每次只有一个线程可以访问关联的资源。只有 0 或 1 值的计数信号灯通常称为二进制信号灯。

如果使用二进制信号灯,用户必须阻止同一个线程对其已拥有的信号灯执行获取操作。第二个获取操作将失败,并且可能导致调用线程无限期挂起和资源永久不可用。

2.1.3 事件通知

还可以采用生成者-使用者的方式,将计数信号灯用作事件通知。使用者尝试获取计数信号灯,而生成者则在有可用的信息时增加信号灯。此类信号灯的初始值通常为 0,此值不会在生成者为使用者准备好信息之前增加。用于事件通知的信号灯也可能从使用 tx_semaphore_ceiling_put 服务调用中获益。此服务确保信号灯计数值永远不会超过调用中提供的值。

2.1.4 创建计数信号灯

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

2.1.5 线程挂起

尝试对当前计数为 0 的信号灯执行获取操作时,应用程序线程可能会挂起。

执行放置操作后,才会执行挂起线程的获取操作并恢复该线程。如果同一计数信号灯上挂起多个线程,这些线程将按照挂起的顺序 (FIFO) 恢复。

不过,如果应用程序在取消线程挂起的信号灯放置调用之前调用 tx_semaphore_prioritize,还可以恢复优先级。信号灯设置优先级服务将优先级最高的线程放于挂起列表的前面,同时让所有其他挂起的线程采用相同的 FIFO 顺序。

2.1.6 信号灯放置通知

某些应用程序可能会发现,在放置信号灯时收到通知十分有利。ThreadX 通过 tx_semaphore_put_notify 服务提供此功能。此服务将提供的应用程序通知函数注册到指定的信号灯。只要放置了信号灯,ThreadX 就会调用此应用程序通知函数。应用程序通知函数内的确切处理由应用程序决定;但这通常包括恢复相应的线程以处理新信号灯放置事件。

2.1.7 运行时信号灯性能信息

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

整个系统的总数:

信号灯放置数

信号灯获取数

信号灯获取挂起数

信号灯获取超时数

每个信号灯的总数:

信号灯放置数

信号灯获取数

信号灯获取挂起数

信号灯获取超时数

此信息在运行时通过tx_semaphore_performance_info_get和 tx_semaphore_performance_system_info_get 服务提供。信号灯性能信息在确定应用程序是否正常运行时非常有用。此信息对于优化应用程序也很有用。例如,“信号灯获取超时数”相对较高可能表明其他线程占用资源的时间太长。

2.2 Azure Threadx 信号量的相关函数

tx_semaphore_create 创建计数信号灯

UINTtx_semaphore_create(
TX_SEMAPHORE*semaphore_ptr,
CHAR*name_ptr,
ULONGinitial_count);

函数说明

此服务创建用于线程间同步的计数信号灯。初始信号灯计数指定为输入参数。

参数

semaphore_ptr:指向信号灯控制块的指针。

name_ptr:指向信号灯名称的指针。

initial_count:指定此信号灯的初始计数。合法值的范围为 0x00000000 至 0xFFFFFFFF。

返回值

TX_SUCCESS:(0X00) 成功创建信号灯。

TX_SEMAPHORE_ERROR:(0x0C) 信号灯指针无效。指针为 NULL 或已创建信号灯。

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

示例

TX_SEMAPHOREmy_semaphore;
UINTstatus;

/*Createacountingsemaphorewhoseinitialvalueis1.
Thisistypicallythetechniqueusedtomakeabinary
semaphore.Binarysemaphoresareusedtoprovide
protectionoveracommonresource.*/
status=tx_semaphore_create(&my_semaphore,
"my_semaphore_name",1);

/*IfstatusequalsTX_SUCCESS,my_semaphoreisreadyfor
use.*/

另请参阅

tx_semaphore_ceiling_put

tx_semaphore_delete

tx_semaphore_get

tx_semaphore_info_get

tx_semaphore_performance_info_get

tx_semaphore_performance_system_info_get

tx_semaphore_prioritize

tx_semaphore_put

tx_semaphore_put_notify

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

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”:

771536d6-7c69-11ed-8abf-dac502259ad0.png

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

77306e74-7c69-11ed-8abf-dac502259ad0.png

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

77556058-7c69-11ed-8abf-dac502259ad0.png

注意:

需要在delay.c中配置USE_SYSTICK_DELAY 为 0。

#define USE_SYSTICK_DELAY 0

3Threadx 的信号量应用

创建如下几个任务:

LED1闪烁指示当前系统运行。

K2键按下,发送信号量同步信号。

任务接收到消息后,串口打印。

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
#defineTHREAD1_PRIORITY2
#defineTHREAD1_PREEMPTION_THRESHOLD2

#defineTHREAD5_PRIORITY4
#defineTHREAD5_PREEMPTION_THRESHOLD4



//#defineTHREAD5_PREEMPTION_THRESHOLD_NEW0


/*DefinetheThreadXobjectcontrolblocks...*/
TX_THREADthread_0;
TX_THREADthread_1;

TX_THREADthread_5;

TX_SEMAPHORESemaphore;

/*Definethecountersusedinthedemoapplication...*/
ULONGthread_0_counter;
ULONGthread_1_counter;

ULONGthread_5_counter;


/*Definethethreadstacks.*/
UCHARthread_0_stack[DEMO_STACK_SIZE];
UCHARthread_1_stack[DEMO_STACK_SIZE];

UCHARthread_5_stack[DEMO_STACK_SIZE];

/*Definethreadprototypes.*/

voidthread_0_entry(ULONGthread_input);
voidthread_1_entry(ULONGthread_input);

voidthread_5_entry(ULONGthread_input);


volatileunsignedintbootloop;

/*Definemainentrypoint.*/



intmain()
{
DELAY_Init();//cannotusesystick
LED_Init();
KEY_Init();
CONSOLE_Init(115200);
printf("!!!Start!!!
");

/*EntertheThreadXkernel.*/
tx_kernel_enter();
}


/*Definewhattheinitialsystemlookslike.*/

voidtx_application_define(void*first_unused_memory)
{
/*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);

/*Createthread1.*/
tx_thread_create(
&thread_1,
"thread1",
thread_1_entry,
0,
thread_1_stack,
DEMO_STACK_SIZE,
THREAD1_PRIORITY,
THREAD1_PREEMPTION_THRESHOLD,
TX_NO_TIME_SLICE,
TX_AUTO_START);


/*Createthread5.*/
tx_thread_create(
&thread_5,
"thread5",
thread_5_entry,
5,
thread_5_stack,
DEMO_STACK_SIZE,
THREAD5_PRIORITY,
THREAD5_PREEMPTION_THRESHOLD,
TX_NO_TIME_SLICE,
TX_AUTO_START);

/*Createasemaphoreforsignalsynchronization*/
tx_semaphore_create(&Semaphore,"Semaphore",0);

}


/*Definethetestthreads.*/

voidthread_0_entry(ULONGthread_input)
{
/*ThisthreadsimplycontrolsLEDflashingtoindicatethatthesystemisrunning*/
while(1)
{
/*Incrementthethreadcounter.*/
thread_0_counter++;

LED1_TOGGLE();

/*Sleepfor200ticks.*/
tx_thread_sleep(200);

}
}

voidthread_1_entry(ULONGthread_input)
{
UINTstatus;
/*Thisthreadsimplysuccessfullyreceivesthesemaphoreandstartstoprintinformation*/
while(1)
{
/*Incrementthethreadcounter.*/
thread_1_counter++;
status=tx_semaphore_get(&Semaphore,TX_WAIT_FOREVER);
if(status==TX_SUCCESS)
{
/*Receivethesemaphore*/
printf("Synchronizationsemaphorereceived
");
}
}
}


voidthread_5_entry(ULONGthread_input)
{
UCHARt=0;
/*Thisthreadsimplyscanbuttonispressedtosendthesemaphore.*/
while(1)
{
/*Incrementthethreadcounter.*/
thread_5_counter++;

t=KEY_Scan(0);
if(KEY1_PRES==t)
{
LED1_TOGGLE();
}
elseif(KEY2_PRES==t){
LED2_TOGGLE();
/*K2ispressedtosendasemaphore*/
tx_semaphore_put(&Semaphore);
}
elseif(KEY3_PRES==t){
LED3_TOGGLE();
}
elseif(KEY4_PRES==t){
LED4_TOGGLE();
}
else{
tx_thread_sleep(10);
}
}
}

3.2 下载与调试

运行程序,板载LED1闪烁。观察串口调试助手,按下K2键,串口打印信息:

77758bf8-7c69-11ed-8abf-dac502259ad0.png

创建信号量初始值为 0,用于信号同步。任务5执行按键扫描,当K2按下时通过tx_semaphore_put发送信号量,对计数值执行加1操作。任务1通过tx_semaphore_get用于信号量接收,对计数值执行减1操作,实际运行情况是K2键每按下一次,串口打印一条信息,Demo演示成功。

4小结

Azure RTOS 使用信号量能够方便地实现任务之间的同步和资源共享机制,结合MM32F3270的强大性能,可以实现Azure RTOS广泛的应用场景。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    16017

    浏览量

    343631
  • RTOS
    +关注

    关注

    20

    文章

    776

    浏览量

    118796
  • 开发板
    +关注

    关注

    25

    文章

    4429

    浏览量

    93995
  • 信号量
    +关注

    关注

    0

    文章

    53

    浏览量

    8257
  • Azure
    +关注

    关注

    1

    文章

    109

    浏览量

    12689

原文标题:灵动微课堂 (第240讲)|使用MM32F3270基于Azure RTOS信号量的应用

文章出处:【微信号:MindMotion-MMCU,微信公众号:灵动MM32MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    使用MM32F3270基于Azure RTOS定时器组的应用

    Azure RTOS ThreadX 是 Microsoft 提供的高级工业级实时操作系统 (RTOS)。它是专门为深度嵌入式实时 IoT 应用程序设计的。Azure
    的头像 发表于 12-29 17:26 1254次阅读

    MM32F3270系列32位MCU的特点有哪些

    上海灵动微电子推出全新主流型MM32F3270系列32位MCU,此款MM32F3270系列是基于M3内核的32位微控制器,MM32F3270适用于要求高集成度的高性能控制领域,如:工业控制、消防监控
    发表于 11-03 07:20

    使用MM32F3270基于Azure RTOS定时器组的应用

    各种产品(包括消费者设备、医疗电子设备和工业控制设备)上的部署次数已达数十亿次。在前文描述移植基本内核的基础上,该应用手册描述了MM32F3270系列MCU结合Azure RTOS ThreadX
    发表于 02-07 14:18

    灵动微电子MM32F3270系列MCU的特点介绍

    上海灵动微电子推出全新主流型MM32F3270系列32位MCU,此款MM32F3270系列是基于M3内核的32位微控制器,MM32F3270适用于要求高集成度的高性能控制领域,如:工业控制、消防监控
    发表于 03-22 16:57 1945次阅读

    【国产MCU移植】MM32F3270 EVBoard

    【国产MCU移植】MM32F3270 EVBoard
    发表于 12-03 17:21 5次下载
    【国产MCU移植】<b class='flag-5'>MM32F3270</b> EVBoard

    基于MM32F3270 以太网 Client使用

    接下来给大家介绍基于TCP包的通讯。内容分为基于MM32F3270以太网Client的使用与基于MM32F3270以太网Server的使用。
    发表于 02-08 15:10 0次下载
    基于<b class='flag-5'>MM32F3270</b> 以太网 Client使用

    MM32F3270 产品手册(中文版)

    MM32F3270 产品手册(中文版)
    发表于 02-23 18:40 0次下载
    <b class='flag-5'>MM32F3270</b> 产品手册(中文版)

    MM32F3270 产品手册(英文版)

    MM32F3270 产品手册(英文版)
    发表于 02-23 18:40 0次下载
    <b class='flag-5'>MM32F3270</b> 产品手册(英文版)

    MM32F3270 勘误表(中文版)

    MM32F3270 勘误表(中文版)
    发表于 02-23 18:42 0次下载
    <b class='flag-5'>MM32F3270</b> 勘误表(中文版)

    MM32F3270 勘误表(英文版)

    MM32F3270 勘误表(英文版)
    发表于 02-23 18:43 0次下载
    <b class='flag-5'>MM32F3270</b> 勘误表(英文版)

    使用MM32F3270基于Azure RTOS事件标志组的应用

    使用MM32F3270基于Azure RTOS事件标志组的应用
    的头像 发表于 10-27 11:31 282次阅读
    使用<b class='flag-5'>MM32F3270</b>基于<b class='flag-5'>Azure</b> <b class='flag-5'>RTOS</b>事件标志组的应用

    使用MM32F3270基于Azure RTOS (ThreadX) 的移植

    使用MM32F3270基于Azure RTOS (ThreadX) 的移植
    的头像 发表于 10-27 10:15 476次阅读
    使用<b class='flag-5'>MM32F3270</b>基于<b class='flag-5'>Azure</b> <b class='flag-5'>RTOS</b> (ThreadX) 的移植

    基于MM32F3270 I2S使用

    基于MM32F3270 I2S使用
    的头像 发表于 09-27 15:50 502次阅读
    基于<b class='flag-5'>MM32F3270</b> I2S使用

    基于MM32F3270以太网Client使用

    基于MM32F3270以太网Client使用
    的头像 发表于 09-27 15:44 439次阅读
    基于<b class='flag-5'>MM32F3270</b>以太网Client使用

    基于MM32F3270以太网UDP使用

    基于MM32F3270以太网 UDP使用
    的头像 发表于 09-27 15:42 283次阅读
    基于<b class='flag-5'>MM32F3270</b>以太网UDP使用