完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
Azure RTOS ThreadX概述 Azure RTOS ThreadX是微软先进的工业级实时操作系统(RTOS),专为嵌入式、实时和物联网应用程序设计。Azure RTOS ThreadX提供先进的调度、通讯、同步、定时器、内存管理和中断管理等功能。此外,Azure RTOS ThreadX还具有许多高级特性,包括它的Picokernel体系结构、抢占阈值调度、事件链接、执行分析、性能度量和系统事件跟踪。结合其优越的易用性,Azure RTOS ThreadX是最苛刻的嵌入式应用程序的理想选择。截至 2017 年,Azure RTOS ThreadX 已在各种产品(包括消费类设备、医疗电子设备和工业控制设备)中部署了超过 62 亿次。 MM32 eMiniBoard开发板 Insight系列MM32 eMiniBoard开发板是灵动微电子推出的基于Cortex-M0/M3系列MCU开发评估板,集成了MM32-LINK-OB在线仿真器,支持SWD调试接口及CDC虚拟调试串口;此外结合MCU的外设,开发板还支持LED、按键、EEPROM、SPI FLASH、蜂鸣器、电位器、串口和CAN通讯等功能,为终端用户的功能验证提供了便捷的开发环境。 资料准备 1 Azure RTOS ThreadX源码 https://github.com/azure-rtos/threadx/releases 2 Azure RTOS ThreadX在线文档 https://docs.microsoft.com/en-us/azure/rtos/threadx/overview-threadx 3 eMiniBoard MB-025开发板用户手册http://www.mindmotion.com.cn/userfiles/images/XiaZaiZhongXin/ug_mm32_emb_v0.92_cn.pdf 4 MM32F0133数据手册及用户手册http://www.mindmotion.com.cn/userfiles/images/MM32F013XiLieWenDang/DS_MM32F013x_V1.00_SC.pdf http://www.mindmotion.com.cn/userfiles/images/MM32F013XiLieWenDang/UM_MM32F013x_V1.00_SC.pdf 5 MM32F0133库函数及例程http://www.mindmotion.com.cn/userfiles/images/KuHanShuHeLiCheng/MM32F013x_Lib_Samples_V1.03.zip 移植Azure RTOS ThreadX 01 功能验证 在eMiniBoard MB-025开发板上创建最小系统工程,使用开发板的UART2和LED外设,通过UART2打印输出消息,并让LED灯间隔闪烁。 02 移植步骤 当前下载的Azure RTOS ThreadX源码版本为6.1.1_rel,解压后如下图所示:
移植需要的两个文件夹分别为ports和common,将这两个文件夹复制到刚刚创建的最小系统工程中,存放路径为:SourceUtilityThreadX,如下图所示:
eMiniBoard MB-025板载的芯片为MM32F0133C7P,是基于Cortex-M0的MCU,软件工程是基于KEIL MDK的AC5编译的,所以我们在移植的时候需要使用的是portscortex_m0ac5文件夹下的内容。 将portscortex_m0ac5example_build文件夹下的tx_initialize_low_level.s文件复制到portscortex_m0ac5src文件夹下。 打开刚刚创建的最小系统工程,点击如下图的Manage Project Items图标,弹出Manage Project Items对话框: 在Manage Project Items对话框中的Project Items选项卡中,在Groups中添加ThreadX_Common和ThreadX_Ports选中ThreadX_Common,添加SourceUtilityThreadXcommonsrc文件夹下的所有源文件 选中ThreadX_Ports, 添加SourceUtilityThreadXportscortex_m0ac5src文件夹下的所有源文件 如下图所示:
点击如下图所示的Options for Target...图标,在弹出的Options for Target对话框的C/C++选项卡中,点击Include Paths,添加Azure RTOS ThreadX头文件路径,如下图所示:
至此,Azure RTOS ThreadX的移植文件就添加OK了,我们尝试编译一下工程,编译结果提示有一个ERROR错误,如下图所示: 这是因为在我们工程中的startup_mm32f013x_keil.s和tx_initialize_low_level.s这两个文件中的定义配置重复冲突引起的。 我们想保留startup_mm32f013x_keil.s这个原厂库函数中提供的启动文件,所以我们来修改tx_initialize_low_level.s这个文件中的实现内容,具体修改如下: IMPORT _tx_thread_system_stack_ptr IMPORT _tx_initialize_unused_memory IMPORT _tx_timer_interrupt IMPORT __initial_sp IMPORT __Vectors SYSTEM_CLOCK EQU 72000000 SYSTICK_CYCLES EQU ((SYSTEM_CLOCK / 1000) - 1) AREA ||.text||, CODE, READONLY VOID _tx_initialize_low_level(VOID) { EXPORT _tx_initialize_low_level _tx_initialize_low_level /* Ensure that interrupts are disabled. */ CPSID i ; Disable interrupts /* Set base of available memory to end of non-initialised RAM area. */ LDR r0, =_tx_initialize_unused_memory ; Build address of unused memory pointer LDR r1, =__initial_sp ; Build first free address ADDS r1, r1, #4 ; STR r1, [r0] ; Setup first unused memory pointer /* Setup Vector Table Offset Register. */ LDR r0, =0xE000ED08 ; Build address of NVIC registers LDR r1, =__Vectors ; Pickup address of vector table STR r1, [r0] ; Set vector table address /* Enable the cycle count register. */ LDR r0, =0xE0001000 ; Build address of DWT register LDR r1, [r0] ; Pickup the current value MOVS r2, #1 ORRS r1, r1, r2 ; Set the CYCCNTENA bit STR r1, [r0] ; Enable the cycle count register /* Setup Vector Table Offset Register. */ LDR r0, =0xE000E000 ; Build address of NVIC registers LDR r2, =0xD08 ; Offset to vector base register ADD r0, r0, r2 ; Build vector base register LDR r1, =__Vectors ; Pickup address of vector table STR r1, [r0] ; Set vector table address /* Set system stack pointer from vector value. */ LDR r0, =_tx_thread_system_stack_ptr ; Build address of system stack pointer LDR r1, =__Vectors ; Pickup address of vector table LDR r1, [r1] ; Pickup reset stack pointer STR r1, [r0] ; Save system stack pointer /* Configure SysTick. */ LDR r0, =0xE000E000 ; Build address of NVIC registers LDR r1, =SYSTICK_CYCLES STR r1, [r0, #0x14] ; Setup SysTick Reload Value MOVS r1, #0x7 ; Build SysTick Control Enable Value STR r1, [r0, #0x10] ; Setup SysTick Control /* Configure handler priorities. */ LDR r1, =0x00000000 ; Rsrv, UsgF, BusF, MemM LDR r0, =0xE000E000 ; Build address of NVIC registers LDR r2, =0xD18 ; ADD r0, r0, r2 ; STR r1, [r0] ; Setup System Handlers 4-7 Priority Registers LDR r1, =0xFF000000 ; SVCl, Rsrv, Rsrv, Rsrv LDR r0, =0xE000E000 ; Build address of NVIC registers LDR r2, =0xD1C ; ADD r0, r0, r2 ; STR r1, [r0] ; Setup System Handlers 8-11 Priority Registers ; Note: SVC must be lowest priority, which is 0xFF LDR r1, =0x40FF0000 ; SysT, PnSV, Rsrv, DbgM LDR r0, =0xE000E000 ; Build address of NVIC registers LDR r2, =0xD20 ; ADD r0, r0, r2 ; STR r1, [r0] ; Setup System Handlers 12-15 Priority Registers ; Note: PnSV must be lowest priority, which is 0xFF /* Return to caller. */ BX lr } EXPORT SysTick_Handler EXPORT __tx_SysTickHandler __tx_SysTickHandler SysTick_Handler VOID TimerInterruptHandler (VOID) { PUSH {r0, lr} BL _tx_timer_interrupt POP {r0, r1} MOV lr, r1 BX lr } ALIGN LTORG END 在修改了tx_initialize_low_level.s文件后,我们再尝试编译一下工程,编译结果又提示了一个错误:SysTick_Handler multiply defined,系统的SysTick中断函数被重复定义了。 在注释上自己实现的SysTick_Handler函数后,我们再来编译一下工程;这个时候编译结果又提示了一个错误:Undefined symbol tx_application_define,没有定义tx_application_define,如下图所示:
我们在main.c中添加一个tx_application_define函数,再重新编译一下工程,这个时候整个工程编译没有错误。 使用MDK v5.31版本,设置-O0优化等级,经过编译后最小资源如下:
此时Azure RTOS ThreadX在MM32F0133的空工程算是移植成功了,接下来我们来添加一个最简的LED闪灯和UART串口打印输出例程,验证一下移植是否成功。 在main.c文件中实现我们上述描述的功能,如下所示: /* Define to prevent recursive inclusion -----------------------------*/ #define __MAIN_C__ /* Includes ----------------------------------------------------------*/ #include "main.h" /* Private typedef ---------------------------------------------------*/ /* Private define ----------------------------------------------------*/ /* Private macro -----------------------------------------------------*/ /* Private variables -------------------------------------------------*/ TX_THREAD mm32_thread1; /* Private function prototypes ---------------------------------- -----*/ /* Private functions --------------------------------------------------*/ /** * @Brief * @param None * @retval None */ void mm32_thread1_entry(ULONG thread_input) { while(1) { LED1_TOGGLE(); printf("rnmm32 thread1 running..."); tx_thread_sleep(1000); } } /** * @brief * @param None * @retval None */ void tx_application_define(void *first_unused_memory) { /* 创建任务 */ tx_thread_create( &mm32_thread1, /* 任务控制块地址 */ "mm32 thread1", /* 任务名称 */ mm32_thread1_entry, /* 启动任务函数地址 */ 0, /* 传递给任务的参数 */ first_unused_memory,/* 堆栈基地址 */ 1024, /* 堆栈空间大小 */ 1, /* 任务优先级 */ 1, /* 任务抢占阈值 */ TX_NO_TIME_SLICE, /* 不开启时间片 */ TX_AUTO_START /* 创建后立即启动 */ ); } /** * @brief 芯片内部资源初始化集合 * @param None * @retval None */ void MCU_Config(void) { SysTick_Init(); /* SysTick系统滴答时钟初始化配置 */ UART2_Config(); /* UART2串口初始化配置 */ } /** * @brief 板载硬件资源初始化集合 * @param None * @retval None */ void BSP_Init(void) { LED_Init(); /* LED灯初始化 */ } /** * @brief * @param None * @retval None */ int main(void) { MCU_Config(); /* 芯片内部资源初始化集合 */ BSP_Init(); /* 板载硬件资源初始化集合 */ /* 打印系统上电初始化完成后的信息 */ printf("rnrneMiniBoard MB-025(MM32F0133C7P) %s %srnrn", __DATE__, __TIME__); /* 启动内核 */ tx_kernel_enter(); while(1) { } } 编译程序无误后将程序下载到开发板运行,查看到LED1每间隔1秒钟闪烁一次,通过串口终端工具可以查看到程序正在运行,每间隔1秒钟打印输出一条信息。 |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
2252个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11823 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5976 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
11116 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4595 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4327 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
1280浏览 1评论
849浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 19:03 , Processed in 0.749557 second(s), Total 61, Slave 46 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号