查看: 3496|回复: 0

将跨界进行到底,在i.MX RT上运行NuttX操作系统

[复制链接]
  • TA的每日心情
    开心
    2025-7-11 08:53
  • 签到天数: 301 天

    连续签到: 2 天

    [LV.8]以坛为家I

    3868

    主题

    7472

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    39232
    最后登录
    2025-7-18
    发表于 2019-7-29 09:31:20 | 显示全部楼层 |阅读模式
    跨界处理器i.MX RT,把MCU的性能提高到一个更高的层次,也把MCU的应用范围大大地扩充了,面对这样性能强大的平台,也需要有性能强大的开发环境做支撑,本文将为MCUer展示一个新的开发路径。


    1,简介


    由于i.MX RT系列微处理器的跨界特性,拥有极高的CPU主频、大容量存储、丰富的外设等诸多高端配置,使得运行一些功能强大的重型类Linux操作系统(比如NuttX等)也成为了可能。


    传统的MCU开发者少有运行这些类Linux操作系统的经验,而且他们更加熟悉Windows平台的开发环境。本文将介绍如何在i.MX RT系列微处理器上用传统MCU 开发者更加熟悉的方式运行NuttX。


    本文使用的PC端环境为Windows 10,硬件环境为i.MX RT1060 EVK。


    2,在Windows 10上运行Ubuntu


    目前微软已经支持在Win10上无虚拟机运行Linux的Ubuntu,安装步骤如下:
    25.png
    2.png
    3.png
    4.png
    5.png
    6.png
    7.png
    8.png
    9.png
    10.png
    这就是我们后面做NuttX开发的Linux环境。
    使用Win10内置Ubuntu的一个最大优势就是,两个OS的文件夹是可以直接共享的。
    Linux的root目录可以通过windows目录直接访问:
    比如小编可以通过下面的Windows目录直接访问Linux目录。
    C:\Users\账户名\AppData\Local\Packages\ CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs
    这样我们代码的编辑等操作就都是完全熟悉的Windows环境,Linux部分就是一个编译开发工具。
    3,构建编译环境
    默认的Linux环境很多工具没有安装,我们需要安装一些工具来进行NuttX的开发。
    下面是需要另外安装的工具列表:
    • sudo apt-get install git
    • sudo apt-get install gcc
    • sudo apt-get install gcc-arm-none-eabi
    • sudo apt install make
    • sudo apt-get install autoconf libtool gperf flex bison  
    • sudo apt-get install autoconf2.13
    • sudo apt-get install libncurses-dev
    • sudo apt-get install libusb-1.0-0-dev
    • sudo apt-get install libsgutils2-dev
    • sudo apt-get install genromfs
    • sudo apt-get install pkg-config

    还有一个工具是自行下载编译后安装的:
    做这一步首先要选择一个工作目录,小编选的是tmp目录。
    11.png
    这期间,小编碰到的问题是,下载后的包编译并不能通过,需要修正代码里面的bug。

    相关的patch如下所示:

    diff --git a/libs/parser/menu.c b/libs/parser/menu.c
    index fd3f018..be07657 100644
    --- a/libs/parser/menu.c
    +++ b/libs/parser/menu.c
    @@ -525,7 +525,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
    {
            int i, j;
            struct menu *submenu[8], *menu, *location = NULL;
    -       struct jump_key *jump;
    +       struct jump_key *jump =NULL;

            str_printf(r, _("Prompt: %s\n"), _(prop->text));
            menu = prop->menu->parent;
    @@ -559,22 +559,27 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
                    list_add_tail(&jump->entries, head);
            }

    -       if (i > 0) {
    -               str_printf(r, _("  Location:\n"));
    -               for (j = 4; --i >= 0; j += 2) {
    -                       menu = submenu;
    -                       if (head && location && menu == location)
    -                               jump->offset = r->len - 1;
    -                       str_printf(r, "%*c-> %s", j, ' ',
    -                                  _(menu_get_prompt(menu)));
    -                       if (menu->sym) {
    -                               str_printf(r, " (%s [=%s])", menu->sym->name ?
    -                                       menu->sym->name : _("<choice>"),
    -                                       sym_get_string_value(menu->sym));
    -                       }
    -                       str_append(r, "\n");
    -               }
    -       }
    +    if(jump)
    +    {
    +        if (i > 0) {
    +            str_printf(r, _("  Location:\n"));
    +            for (j = 4; --i >= 0; j += 2) {
    +                menu = submenu;
    +                if (head && location && menu == location)
    +                    jump->offset = r->len - 1;
    +                str_printf(r, "%*c-> %s", j, ' ',
    +                       _(menu_get_prompt(menu)));
    +                if (menu->sym) {
    +                    str_printf(r, " (%s [=%s])", menu->sym->name ?
    +                        menu->sym->name : _("<choice>"),
    +                        sym_get_string_value(menu->sym));
    +                }
    +                str_append(r, "\n");
    +            }
    +        }
    +
    +    }
    +

    }

    4,下载NuttX

    NuttX的下载地址可以在其官网找到:http://www.nuttx.org/




    注意下载的目录结构是有讲究的,小编的目录是这样的:
    12.png
    小编在tmp目录下建立了nuttx_test目录,然后作为nuttx的工作目录。

    5,编译NuttX系统

    到这里,如果是传统MCU的玩家,基本上就不知道怎么搞了,因为这个系统非常复杂。

    在研究了相关的步骤后,发现对于这类RTOS的玩法,其实只有两个步骤:

    1. 配置系统。

    首先进入的nuttx目录,然后执行:

    ./tools/configure.sh imxrt1060-evk/nsh

    这个命令的含义是,用configs目录下的imxrt1060-evk/nsh配置参数来配置NuttX。这一步非常重要,因为NuttX这样的OS支持非常广泛的CPU类型和开发板,我们需要使用i.MX RT对应的参数来配置NuttX。

    这一步执行完成后有可能系统会报错,原因是CONFIG_APPS_DIR的定义不对。需要在config 文件中修改如下:

    CONFIG_APPS_DIR="../apps"

    然后执行这个命令来清除之前的配置信息:

    make distclean

    然后再一次运行./tools/configure.sh imxrt1060-evk/nsh对系统进行配置。

    2. 编译系统

    配置完成后,就可以编译NuttX系统了。

    这只需要执行:

        make

    6,运行编译后的Image


    编译完成后,会生成最终的image文件nuttx.hex
    13.png
    编译完成后通过拖拽(复制粘贴)的方式,即可把image编程到EVK上。
    14.png
    然后复位EVK,就可以看到Nuttx已经跑起来了。
    15.png
    7,加载例程

    例程Example都在APP目录中,默认情况下没有Example被编译到目标image中去。


    添加example的方法是在rootfs\tmp\nuttx_test\nuttx\configs\imxrt1060-evk\nsh目录下,编辑defconfig。
    16.png
    然后执行:

        > make distclean

        > ./tools/configure.sh imxrt1060-evk/nsh

        > make


    烧录并且运行image后,可以看到Builtin Apps里面就有hello example了。 
    17.png
    然后在命令行里面输入hello,即可运行hello 例程。

    8,关于NuttX的启动流程

    考虑到有的应用是期待系统上电后能够自动运行,这需要了解系统的启动流程。这里引用一篇很好的文章介绍启动流程。


    在os_do_appstart函数中,实现app 相关的初始化,这里是OS到APP入口。

    9,编译Tizen

    Tizen是NuttX的一个由Samsung主导的演进版本。相关链接是:

    http://github.com/Samsung/TizenRT


    9.1. 使用docker环境进行编译

    Tizen的编译首选是使用docker, docker会自动搭建编译Tizen的工具链,非常方便。

    Docker的安装指南:

    http://docs.docker.com/install/linux/docker-ce/ubuntu/

    安装好docker后,执行:

        cd os

        ./dbuild.sh menu

    然后会有菜单选择目标板以及工程。


    选择2,配置系统。
    18.png
    选择7,RT1020目标板。
    19.png
    选择1, nxp_demo。
    20.png
    配置完成后选择1,编译系统。
    21.png
    编译过程比较长,要10来分钟。

    编译完成后会在TizenRT\build\output\bin目录输出image文件。
    22.png
    在链接RT1020 EVK的CMSIS-DAP接口的情况下,可以使用d选项下载image到板上,然后就可以复位目标板运行Tizen OS了。
    23.png
    9.2. 手动编译(非docker环境)

    由于小编的电脑受到公司的权限限制,无法正常使用docker,于是尝试手动编译。手动编译最大的问题是要自己搭建tool chain。相关的链接是:

    http://github.com/Samsung/TizenRT/blob/master/docs/HowToSetEnv.md

    但是这个链接讲述的内容不完整,相信如果只是参考这个链接是无法编译Tizen的。

    本文前面已经介绍了手动搭建环境编译原生NuttX的步骤,在前面的基础上需要安装:

        sudo apt-get install memstat

        sudo apt-get install python

    然后就可以直接不使用docker编译Tizen了。

    相关的命令是:

    cd os/tools

    ./configure.sh imxrt1020-evk/nxp_demo (这个是需要根据不同的目标板和例程进行调整的)

    然后:

        cd ..

        make


    大功告成!
    24.png
    10,一些感受

    作为一个MCU的传统玩家,这次玩NuttX首先得到了同事Magicoe的鼎力相助,两个小时把第一个版本在Mac OS上跑了起来。这是非常巨大的帮助,为后面的工作节省了大量探索的时间。

    由于Mac操作不习惯,开发效率不高,小编最终还是希望能在Windows的环境下进行高效率的开发,于是开始探索怎么在Windows下面玩NuttX。

    NuttX官网上有很好的介绍,不少内容都值得研读。另外Readme.txt里面有很多重要的信息,不少是作者很用心写的。缺点就是完全是txt,看着很累。但是碰到很多问题解决不了,还是只能硬着头皮读。最终的结论就是,这些readme.txt确实是大师之作,好好的读一下确实很有收获。小编最后惊讶的发现,陆陆续续竟然把root下面的那个txt给读完了。

    另外就是做的过程中,总是有很多的问题,并没有一个很好的教程可以直接把结果做出来。开源软件很大的一个问题就是,环境的不一致,可能导致各种各样的问题。很多时候赖着性子在网上找答案。百度可以解决一部分问题,但是百度一定不能解决所有的问题。这个时候还是得靠Google。

    很多时候这玩意真的很让人崩溃,都是快要放弃的时候,突然想到或者搜索到了重要的信息。那个时候会觉得,自己其实并不是一个人在战斗。Docker能很好的解决这个问题,自动搭建环境,是一个不错的选择,如果能使用docker,就要尽量使用docker。

    这次能在Win10的内置Ubuntu环境下把NuttX boot起来,感觉运气也真的是很重要。


    感谢运气!


    作者:郭嘉        文章出处:恩智浦MCU加油站

    qiandao qiandao
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-20 06:47 , Processed in 0.088174 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表