[MCU] 【HC32F460开发板测评】NO.4 ThreadX移植

yang377156216   2021-4-26 18:02 楼主

Azure RTOS全家桶

微软在2019年对Express Logic的收购将其ThreadX实时操作系统带入了Azure。 现在已被称为Azure RTOS(开源的主页为 https://github.com/azure-rtos ,它是一种工业级实时操作系统。ThreadX及其所有中间件的安全认证等级,至今没有一款小型RTOS可以与其匹敌。

  1. 医疗-FDA510(k),IEC-62304ClassC,IEC-60601,ISO-14971
  2. 工业-UL-1998,IEC-61508SIL4
  3. 运输/铁路-EN50128SIL4,BS50128,49CFR236,IEC-61508
  4. 航空航天设备-DO-178B,ED-12B,DO-278
  5. 汽车-IEC-61508ASILD
  6. 核应用-IEC-61508
  7. 家电-UL/IEC60730/60335

各种安全等级基本都达到了最高。像工业级安全认证IEC61508,ThreadX满足最高等级SIL4,而SafeRTOS,embOS,uCOS-II都只是SIL3。

ThreadX和它功能极为全面各种中间件如下图

image.png

ThreadXHC32F460上的移植

ThreadX的体系结构的一个优势是,很容易移植到新的芯片体系结构。现在拿前一节准备好的并且测试正常的OLED显示工程,直接移植,以下是过程。

下载内核源码

内核源码可以在官方的Github下载:https://github.com/azure-rtos/threadx 将源码中的common和ports文件夹复制到工程中:

image.png

添加Port文件和源码文件到工程

将源码文件和ports文件添加到MDK的工程项目中,添加后的效果如下:

image.png

ThreadX/Ports分组文件位置

文件tx_initialize_low_level.s在路径ThreadX\ports\cortex_m4\ac5\example_build其它文件在路径ThreadX\ports\cortex_m4\ac5\src

ThreadX/Source分组文件位置

全部在路径ThreadX\common\src,所有文件全部添加进来推荐使用下面的方法添加,有效防止MDK大批量添加源文件造成的卡顿问题:

image.png 添加所有相关的源码文件,然后添加好工程的头文件路径以及添加相关预定义宏

image.png  

image.png

修改初始化代码

原工程默认跑8MHz时钟,现需要修改时钟配置,更改到 200MHz主频

/* Define the initial systemcore clock.  */
void CLK_SwitchTo200MHz()
{
    en_clk_sys_source_t     enSysClkSrc;
    stc_clk_sysclk_cfg_t    stcSysClkCfg;
    stc_clk_xtal_cfg_t      stcXtalCfg;
    stc_clk_mpll_cfg_t      stcMpllCfg;
    stc_clk_freq_t          stcClkFreq;
    stc_clk_output_cfg_t    stcOutputClkCfg;
    stc_sram_config_t       stcSramConfig;

    MEM_ZERO_STRUCT(enSysClkSrc);
    MEM_ZERO_STRUCT(stcSysClkCfg);
    MEM_ZERO_STRUCT(stcXtalCfg);
    MEM_ZERO_STRUCT(stcMpllCfg);

    /* Set bus clk div. */
    stcSysClkCfg.enHclkDiv = ClkSysclkDiv1;
    stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;
    stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;
    stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;
    stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;
    stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;
    stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;
    CLK_SysClkConfig(&stcSysClkCfg);

    /* Config Xtal and Enable Xtal */
    stcXtalCfg.enMode = ClkXtalModeOsc;
    stcXtalCfg.enDrv = ClkXtalLowDrv;
    stcXtalCfg.enFastStartup = Enable;
    CLK_XtalConfig(&stcXtalCfg);
    CLK_XtalCmd(Enable);
    /* Switch system clock source to XTAL. */
    CLK_SetSysClkSource(ClkSysSrcXTAL);
    /* Use Xtal as MPLL source. */
    /* MPLL config (XTAL / pllmDiv * plln / PllpDiv = 50M). */
    stcMpllCfg.pllmDiv = 1ul;
    stcMpllCfg.plln = 50ul;
    stcMpllCfg.PllpDiv = 8ul;
    stcMpllCfg.PllqDiv = 8ul;
    stcMpllCfg.PllrDiv = 8ul;
    CLK_SetPllSource(ClkPllSrcXTAL);
    CLK_MpllConfig(&stcMpllCfg);
    /* flash read wait cycle setting */
    EFM_Unlock();
    EFM_SetLatency(EFM_LATENCY_1);
    EFM_Lock();
    /* sram init include read/write wait cycle setting */
    stcSramConfig.u8SramIdx = Sram12Idx | Sram3Idx | SramHsIdx | SramRetIdx;
    stcSramConfig.enSramRC = SramCycle2;
    stcSramConfig.enSramWC = SramCycle2;
    stcSramConfig.enSramEccMode = EccMode3;
    stcSramConfig.enSramEccOp = SramNmi;
    stcSramConfig.enSramPyOp = SramNmi;
    SRAM_Init(&stcSramConfig);
    /* Enable MPLL. */
    CLK_MpllCmd(Enable);
    /* Wait MPLL ready. */
    while (Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
    {
        ;
    }
    /* Switch system clock source to MPLL. */
    CLK_SetSysClkSource(CLKSysSrcMPLL);
    /* Check source and frequency. */
    enSysClkSrc = CLK_GetSysClkSource();
    CLK_GetClockFreq(&stcClkFreq);
    /* flash read wait cycle setting */
    EFM_Unlock();
    EFM_SetLatency(EFM_LATENCY_4);
    EFM_Lock();
    /* Switch driver ability */
    PWC_HS2HP();

    /* MPLL config (XTAL / pllmDiv * plln / PllpDiv = 200M). */
    stcMpllCfg.pllmDiv = 1ul;
    stcMpllCfg.plln = 50ul;
    stcMpllCfg.PllpDiv = 2ul;
    stcMpllCfg.PllqDiv = 2ul;
    stcMpllCfg.PllrDiv = 2ul;
    CLK_SetPllSource(ClkPllSrcXTAL);
    CLK_MpllConfig(&stcMpllCfg);
    SystemCoreClock = 200000000 ;
}

需要将startup_hc32f46x.s 中的堆栈大小加大

Stack_Size      EQU     0x00001400

Heap_Size       EQU     0x00000600

修改文件tx_initalize_low_level.s

ThreadX为MDK AC5提供的这个文件有点欠妥,因为ThreadX通过这个文件直接接管了我们一直使用的xxxx.S启动文件。但接管的文件仅写了几个重要的中断向量表入口。这就给让移植的人非常不方便。所以我们做的例子不接管XXX.S启动文件了,方便大家移植。本周教程配套例子使用的这个文件已经做了修改,推荐大家直接复制粘贴到自己的工程即可,内容如下:

注意:下面代码中置红部分的参数需要大家配置,即芯片主频和系统时钟节拍。

SYSTEM_CLOCK       EQU     200000000

SYSTICK_CYCLES     EQU     ((SYSTEM_CLOCK / 1000) -1)

200000000是系统时钟主频,1000对应的就是系统时钟节拍,这里1000就表示1000Hz。

其它的修改详见附件工程即可。

添加ThreadX配置文件tx_user.h

ThreadX内核相关的配置,已经全部整理到了这个文件中,并且做中文注释,大家可以更新需要使能宏定义。本工程中全部注释掉。

添加应用程序

应用程序比较简单,大家可以直接复制本章教程配置例子的main.c文件中的内容到自己工程里面测试。主要tx_application_define里面创建个任务:

thread_0_entry  :闪灯任务

thread_1_entry :OLED显示任务

本次评测内容主要介绍了移植思路,具体可以参考后续文章中的附件工程,另外需要掌握ThreadX内核框架设计,这有助于移植。

实验现象:可以看到板载的LED每秒闪烁一次,另外显示屏会有显示:

image.png

 

回复评论 (5)

想当初,ThreadX作为一种工业级实时操作系统也很有市场潜力的

无奈微软财大气粗

点赞  2021-4-26 21:49

这个评测角度好,期待楼主更多内容分享。

加油!在电子行业默默贡献自己的力量!:)
点赞  2021-4-27 11:26

大佬大佬,跪求该工程!!!万分感谢

点赞  2023-2-22 11:35

已经用上了!

默认摸鱼,再摸鱼。2022、9、28
点赞  2023-2-24 16:46
谢谢分享
点赞  2023-10-11 14:28
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复