<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

移植Arm-2D到i.MX RT1050-EVKB并繪制圖形界面

恩智浦MCU加油站 ? 來源:恩智浦MCU加油站 ? 作者:恩智浦MCU加油站 ? 2022-06-23 09:33 ? 次閱讀

一、引言

眾所周知,i.MX RT系列是MCU中的性能強者,超高的主頻、豐富的外設以及足夠大的存儲使其能輕松應用于各類領域。其中,在圖像視頻方面,i.MX RT1050及以上系列,集成了PXP圖形加速器,可用于對LCD顯示之前的圖像進行處理。

i.MX RT1170更是集成了支持OpenVG的GPU2D模塊,可用于矢量繪圖等操作,還集成了兩類LCD控制器eLCDIF和LCDIFv2,并且在物理接口方面增加了MIPI DSI的支持。

不過強大的硬件支持不是今天文章的重點,今天來玩點“軟”的。

去年,Arm在其Github上發布了一個針對全體Cortex-M處理器的2D圖形加速庫——Arm-2D(暫定名)。在其Github倉庫的文檔中可以看出,Arm-2D致力于打造一層抽象層,為芯片供應廠商提供的硬件以及GUI廠商提供的圖形圖形庫之間的接口設立一層驅動標準。并且Arm-2D也提供了一系列的2D圖形加速API。

本文以移植Arm-2D到i.MX RT1050-EVKB并繪制一些圖形界面為例,動手部署。

二、準備工作

1. 工程下載

首先,我們需要獲取Arm-2D庫,打開其官方github倉庫:https://github.com/ARM-software/EndpointAI,可以看到有四個branch可以選擇,此處選擇developing分支(用于開發的分支,更新相對頻繁)。

下載到本地后,將Arm-2D目錄(EndpointAI-main-arm-2d-developingKernelsResearchArm-2D)拷貝到我們的目標工程目錄下,這里我們選擇i.MX RT1050的SDK中elcdif_rgb工程,以IAR工程為例。打開IAR工程,將”Arm-2D”下的”Helper”和”Library”全部文件添加到工程中。

772e7fd2-f290-11ec-ba43-dac502259ad0.png

2. 環境配置

將”Arm-2D/Library/Include”和”Arm-2D/Helper/Include”添加到Include搜索路徑列表里,接著開始配置工程所需的選項。

在Arm-2D的官方介紹中,我們知道其依賴于CMSIS,并且需要CMSIS 5.7.0及以上的版本。

打開IAR的安裝位置,轉到armCMSIS位置下,點開readme_patch.txt查看是否是5.7.0及以上版本。若你的CMSIS版本為5.7.0以下,請下載新版本,以替換原CMSIS文件。

確定了足夠高的版本后,在工程配置中的”General Options-Library Configuration”中勾選上”USECMSIS”和”DSP Library”。

774767d6-f290-11ec-ba43-dac502259ad0.png

3.關鍵函數

Arm-2D只負責軟件層面的圖形操作,而硬件部分則需要我們自己實現,所以此處我們選用SDK中,已經實現好LCD初始化的elcdif_rgb工程進行部署。

我們所需要做的是,提供一個向LCD指定區域傳送位圖的函數。而i.MX RT1050自帶LCD控制器,則更方便實現所需的操作。

所需傳送位圖的函數如下:

/* i.MX RT1050-EVK */
#define GLCD_WIDTH     480
#define GLCD_HEIGHT    272

#define LCD_BASE_ADDR   0x81E00000  //m_ncache_start 
#define frame_buf         ((volatile uint16_t *)LCD_BASE_ADDR)

int32_t GLCD_DrawBitmap (uint32_t x, uint32_t y, uint32_t width, uint32_t height, const uint8_t *bitmap)
{
    volatile uint16_t *phwDes = frame_buf + y * GLCD_WIDTH + x;
    const uint16_t *phwSrc = (const uint16_t *)bitmap;
    for (int_fast16_t i = 0; i < height; i++) {
        memcpy ((uint16_t *)phwDes, phwSrc, width * 2);
        phwSrc += width;
        phwDes += GLCD_WIDTH;
    }
    return 0;    
}

以上可以直接用存儲器讀寫操作將需要傳送的位圖傳到LCD指定位置,其中顯示緩存的基地址是linker文件中的m_ncache_start。

參數‘x’和’y’描述需要在LCD中顯示的起始位置;參數’width’和’height’描述所傳位圖的尺寸;而參數’bitmap’則代表位圖數據。

三、圖形繪制

1. 畫第一個方塊

接下來嘗試利用Arm-2D進行圖形繪制了。

首先,原工程中保留硬件配置以及外設初始化的部分,將frameBuffer的操作去除。

接著,在需要用到Arm-2D的地方包含頭文件”arm_2d.h”,并在主函數中進行初始化,調用”arm_2d_init();”。此處,我們需要用到Arm-2D的PFB(partial framebuffer),在需要用到PFB Helper的地方包含”arm-2d_helper.h”,建立一個PFB對象并利用其進行我們所需圖像的構建。

以下為PFB的初始化代碼:

static arm_2d_helper_pfb_t s_tExamplePFB;

    //! initialise FPB helper
    if (ARM_2D_HELPER_PFB_INIT( 
            &s_tExamplePFB,                 //!< FPB Helper object
            APP_IMG_WIDTH,                //!< screen width
            APP_IMG_HEIGHT,                //!< screen height
            uint16_t,                        //!< color date type
            PFB_BLOCK_WIDTH,               //!< PFB block width
            PFB_BLOCK_HEIGHT,              //!< PFB block height
            1,                              //!< number of PFB in the PFB pool
            {
                .evtOnLowLevelRendering = {
                    //! callback for low level rendering 
                    .fnHandler = &__pfb_render_handler,                         
                },
                .evtOnDrawing = {
                    //! callback for drawing GUI 
                    .fnHandler = &__pfb_draw_handler, 
                },
            }
        ) < 0) {
        //! error detected
        assert(false);
    }

在此函數中,可以設置在屏中顯示的大小、像素的數據類型、PFB的規格以及PFB的數量,并設置底層渲染函數” __pfb_render_handler”以及圖形繪制函數”__pfb_draw_handler”。

底層渲染函數” pfb_render_handler”用來將PFB中處理好的圖像數據渲染到屏幕的指定位置進行顯示:

static IMPL_PFB_ON_LOW_LV_RENDERING(__pfb_render_handler)
{
    const arm_2d_tile_t *ptTile = &(ptPFB->tTile);

    ARM_2D_UNUSED(pTarget);
    ARM_2D_UNUSED(bIsNewFrame);

    GLCD_DrawBitmap(ptTile->tRegion.tLocation.iX,
                    ptTile->tRegion.tLocation.iY,
                    ptTile->tRegion.tSize.iWidth,
                    ptTile->tRegion.tSize.iHeight,
                    ptTile->pchBuffer);

    arm_2d_helper_pfb_report_rendering_complete(&s_tExamplePFB, 
                                                (arm_2d_pfb_t *)ptPFB);
}

而圖形繪制函數”__pfb_draw_handler”則是利用Arm-2D庫里的各類API進行圖形的繪制。下面就在此函數中簡單繪制一個圖形以演示:

static IMPL_PFB_ON_DRAW(__pfb_draw_handler)
{
    ARM_2D_UNUSED(pTarget);
    ARM_2D_UNUSED(bIsNewFrame);

    arm_2d_region_t tBox = {
        .tLocation = {50,50},    //設定目標坐標
        .tSize = {200, 100},     //設定目標大小
    };
    //! 利用此函數向整個PFB填充白色
    arm_2d_rgb16_fill_colour(ptTile, NULL, 0xFFFF);
    //! 向指定box區域填充黑色
    arm_2d_rgb16_fill_colour(ptTile, &tBox, 0x0000);
    //! 更改box的坐標,大小不變
    tBox.tLocation.iX -= 10;
    tBox.tLocation.iY -= 10;
    //! 向修改后的box指定區域填充藍色,并且使用 50%(128/255)的透明效果
    arm_2d_rgb565_fill_colour_with_alpha(   
        ptTile, 
        &tBox, 
        (arm_2d_color_rgb565_t){0x001F},     //填充藍色
        128);      //!< 透明度

    return arm_fsm_rt_cpl;
}

以上就繪制了如下圖的一個簡單圖標:

775c388c-f290-11ec-ba43-dac502259ad0.png

這里是利用”arm_2d_rgb16_fill_colour”和” arm_2d_rgb565_fill_colour_with_alpha”兩個API進行矩形的繪制,可以看出這是16位RGB格式的色彩填充,當然庫中也提供了32位RGB格式以及8位圖的繪制函數;庫中還提供”arm_2dp_rgb16_draw_point”的畫點函數和”arm_2dp_rgb16_draw_pattern”的畫圖函數。當然,想做一個圖形驅動標準,肯定不止有draw這么基礎的能力,Alpha blending,Rotation等一系列圖形處理的功能都需要支持。

2. 做一個表盤界面

現在,將各項功能綜合運用起來,做一個圖形界面試試。

首先,掏出我們“祖傳”LOGO,將其轉化為特定格式的數組,用的是Arm-2D庫中提供的工具,具體位置為”EndpointAIKernelsResearchArm-2D ools”,用法也在其中,考慮到1050-EVK所用的屏幕為480*272,此處將logo圖壓縮成512*280(比屏幕大,可做出背景移動的效果):”python img2c.py -i .logo.jpg --dim 512 280 --name logo”。

將生成的logo.c文件放到工程中。

777b46a0-f290-11ec-ba43-dac502259ad0.png

除了背景,其余的表盤以及指針等圖像文件我們就用Arm-2D提供的例程里的。

在工程欄中新建”asset”分組,將” ..Arm-2Dexamplescommonasset”中除了”background.c”之外的c文件都選進去,并將之前生成的”logo.c”文件也加入其中,以logo圖作為本次的背景。這一步是將所需的貼圖都加進去。

接著,按照”watch_panel”的工程布局將需要的文件添加:”example_gui.c”和”example_gui.h”,并且依據工程修改主函數、補齊相關的配置。

  1. 程序運行時,先進行相關的硬件配置及初始化操作,再進行Arm-2D的初始化” arm_2d_init()”,到這里都和上一節畫一個矩形是一樣的;
  2. 接著,我們需要對繪制界面中刷新層進行初始化“example_gui_init()”,函數定義在“example_gui.c”中;
  3. 進行PFB的配置,與上節不同的是,將” pfb_draw_handler”改成“pfb_draw_background_handler”,而” pfb_draw_handler”需要留到后面進行圖形繪制用;
  4. 在PFB配置完成后,調用PFB任務“arm_2d_helper_pfb_task(&s_tExamplePFB,NULL)”,其中第二個參數為所需刷新的臟矩陣(DirtyRegions)區域,“NULL”則表示需要全屏刷新;
  5. 調用圖形繪制函數“ARM_2D_HELPER_PFB_UPDATE_ON_DRAW_HANDLER(&s_tExamplePFB, &__pfb_draw_handler);”,其中繪制的部分都在“draw_handler”中的” example_gui_refresh”函數中,對之前添加進工程的貼圖進行各種操作就在這里進行,具體可見“example_gui.c”;
  6. 最后,通過“while(1)”使程序運行在“display_task”中,對顯示屏指定區域的刷新、圖像的一些更新都在此實現。

經過以上的一通操作之后,效果如下動圖所示:

7798f95c-f290-11ec-ba43-dac502259ad0.gif

從上可以看出,此工程中用了bit blit, alpha blending, rotation等效果:
  1. logo滾動背景利用一定范圍內不斷變換坐標的貼圖來實現;
  2. 表盤利用”arm_2d_rgb565_alpha_blending_with_colour_masking”確定指定的透明度顏色蒙版來實現;
  3. 兩個旋轉齒輪以及一根旋轉表針,通過” arm_2dp_rgb565_tile_rotation_with_alpha”區分透明度以及確定旋轉中心來分別實現。

四、總結

至此,基本的Arm-2D圖形繪制功能在i.MX RT1050-EVK上的實現就介紹完了。

本文只是簡單移植一個包含Arm-2D繪圖庫實現某些動畫效果的例子,已經可以看到其多樣的功能,至于更多的一些效果,留給我們的想象空間還很足......

本文只是開篇,后續,還會有對于Arm-2D在i.MX RT上更多的應用介紹。

原文標題:在i.MX RT10XX平臺上部署Arm-2D

文章出處:【微信公眾號:恩智浦MCU加油站】歡迎添加關注!文章轉載請注明出處。

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • mcu
    mcu
    +關注

    關注

    146

    文章

    16035

    瀏覽量

    343868
  • ARM
    ARM
    +關注

    關注

    134

    文章

    8659

    瀏覽量

    362167
  • 移植
    +關注

    關注

    1

    文章

    367

    瀏覽量

    27859
  • 圖形界面
    +關注

    關注

    0

    文章

    37

    瀏覽量

    7299

原文標題:在i.MX RT10XX平臺上部署Arm-2D

文章出處:【微信號:NXP_SMART_HARDWARE,微信公眾號:恩智浦MCU加油站】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    I.MX RT1052代碼執行在哪里?

    試用的開發板里有了I.MX RT1052 但是看I.MX RT1052有代碼與數據的SPI Flash,還有SRAM,還有片上的TCM 代碼可以執行在TCM上么?還是在SRAM上運行。
    發表于 11-09 06:49

    基于NXP i.MX RT117H智能人機界面方案

    基于NXP i.MX RT117H智能人機界面方案
    的頭像 發表于 10-30 18:22 ?361次閱讀
    基于NXP <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>117H智能人機<b class='flag-5'>界面</b>方案

    i.MX RT中FlexSPI外設不常用的讀選通采樣時鐘源

    i.MX RT中FlexSPI外設不常用的讀選通采樣時鐘源
    的頭像 發表于 10-30 17:44 ?275次閱讀
    <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>中FlexSPI外設不常用的讀選通采樣時鐘源

    i.MX RT1050上如何實現雙大容量存儲(MSC)設備

    i.MX RT1050上如何實現雙大容量存儲(MSC)設備
    的頭像 發表于 10-30 17:08 ?346次閱讀
    在<b class='flag-5'>i.MX</b> <b class='flag-5'>RT1050</b>上如何實現雙大容量存儲(MSC)設備

    RT-Thread公司的Persimmon圖形界面是否必須依賴RTT操作系統?

    RT-Thread公司的Persimmon圖形界面是否必須依賴RTT操作系統?
    發表于 10-28 07:38

    i.MX RT的FlexRAM配置問題

    i.MX RT的FlexRAM配置問題
    的頭像 發表于 10-24 15:46 ?293次閱讀
    <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>的FlexRAM配置問題

    M480使用emWin的API繪制圖形

    界面( HMI) 很簡單。 這個示例代碼使用 M480 MCU , 使用 emWin 的 API 來繪制圖形, 可以用作更改面板文字編輯值的按鈕。 emWin 可以輕松地執行如何使用圖形
    發表于 08-30 08:58

    如何使用emWin的API繪制圖形

    界面( HMI) 很簡單。 這個示例代碼使用 M480 MCU , 使用 emWin 的 API 來繪制圖形, 可以用作更改面板文字編輯值的按鈕。 emWin 可以輕松地執行如何使用圖形
    發表于 08-23 07:37

    如何配置i.MX RT1064的RTS_B初始狀態?

    我將 i.MX RT1064 引腳 B2 配置為 RTS_B,我注意到我無法配置此功能的初始狀態。這個管腳在RS-485應用中是可以工作的,但是我發現在MCU復位后這個管腳的初始狀態是高電平。在執行
    發表于 06-12 07:17

    i.MX RT的FreeRTOS MCUXpresso工程中添加runtime

    在調試 i.MX RT FreeRTOS MCUXpresso SDK工程的時候, 很多網友需要添加查看每個task的runtime功能。
    的頭像 發表于 06-09 09:30 ?990次閱讀
    在<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>的FreeRTOS MCUXpresso工程中添加runtime

    如何將第二個(自定義)引導加載程序 + 應用程序移動到 i.MX RT1050平臺上的SDRAM?

    i.MX RT1050 EVKB 上,我開發了第二個引導加載程序,包括從 QSPI 閃存執行的 XIP,然后我開發了一個應用程序,我在其中定義了 XIP_EXTERNAL_FLASH = 1宏
    發表于 05-29 09:00

    RT1050/1060/1064在硬件層面可以互換嗎?我需要改變什么?

    我正在為我們的控制器使用 K66 和 KV58。 1) 我被告知 NXP 將更新 i.MX RT 系列而不是 K 和 KV 系列。我想開始開發基于 i.MX RT 系列的控制器。
    發表于 05-19 12:43

    i.MX RT10xx使用FlexIO實現XY2-100振鏡控制協議

    本文介紹了如何使用i.MX RT系列芯片上的FlexIO實現XY2-100激光振鏡控制協議。FlexIO模塊是NXP Kinetis和i.MX RT系列MCU的片上外設。
    的頭像 發表于 05-18 09:21 ?4081次閱讀
    在<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>10xx使用FlexIO實現XY2-100振鏡控制協議

    i.MX RT系列(例如 RT1050/1060)有多少個PWM通道?

    i.MX RT 系列(例如 RT1050/1060)有多少個 PWM 通道? 我可以像在 KV58 MCU(兩個 flexPWM 模塊)上做同樣的事情嗎?
    發表于 05-18 07:07

    i.MX RT1170自定義引導加載程序,如何在i.MX RT處理器上完成?

    ))vt->reset)(); 跳之前是不是還有更多的步驟要注意? 2)與主應用程序相關,在我以前的引導加載程序中,我必須在跳轉后再次設置中斷向量表。這是如何在 i.MX RT 處理器上完成的?
    發表于 05-17 08:13
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>