當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 裸機(jī)思維
[導(dǎo)讀]在前面的文章《【喂到嘴邊了的模塊】準(zhǔn)備徒手?jǐn)]GUI?用Arm-2D三分鐘就夠了》中,我們介紹了如何借助 cmsis-pack 快速的在 MDK 中部署 arm-2d。

【說(shuō)在前面的話】


在前面的文章《【喂到嘴邊了的模塊】準(zhǔn)備徒手?jǐn)]GUI?用Arm-2D三分鐘就夠了》中,我們介紹了如何借助 cmsis-pack 快速的在 MDK 中部署 arm-2d。
在過(guò)去的一段時(shí)間內(nèi),想必很多人都完成了部署,看到了下面的畫(huà)面吧?


如果還沒(méi)有,推薦先跟著上一篇文章的手把手圖文教程——完成基本的部署吧。本文將在此基礎(chǔ)上繼續(xù)為您介紹如何使用arm-2d來(lái)簡(jiǎn)化我們手?jǐn)]GUI的過(guò)程。

為了避免讓大家產(chǎn)生疑惑,這里我們需要再次明確一下我們所要面對(duì)的開(kāi)發(fā)環(huán)境:
  • 資源相對(duì)緊張的MCU,無(wú)法負(fù)擔(dān)起傳統(tǒng)的嵌入式GUI(比如以體積“小巧”著稱(chēng)的LVGL):
    • Flash <= 64K,或者
    • 應(yīng)用本身已經(jīng)占用了大量Flash空間,留給GUI的空間非常有限
    • SRAM <= 16K
  • 需要實(shí)現(xiàn)的GUI界面較為簡(jiǎn)單(這點(diǎn)在隨后會(huì)詳細(xì)介紹)
  • 幀率要求較低(傳說(shuō)中的8幀不卡、9幀流暢、10幀電競(jìng))


【基于面板的界面設(shè)計(jì)】


從用戶的角度來(lái)說(shuō),如果一個(gè)嵌入式產(chǎn)品帶了彩屏,很自然的就會(huì)希望它能提供像智能手機(jī)(或平板設(shè)備)一樣的操作體驗(yàn)——但從開(kāi)發(fā)者的角度來(lái)說(shuō),用戶的這一期望往往會(huì)被錯(cuò)誤的理解為:用戶希望嵌入式產(chǎn)品上的圖形界面能像手機(jī)那樣支持“這樣或那樣”的滑動(dòng)、滾動(dòng)效果——如果能做到當(dāng)然最好,但其實(shí)這并不是這些“類(lèi)智能手機(jī)界面”設(shè)計(jì)的核心。
讓我把話挑明了吧——流暢的滑動(dòng)只是添料,甚至是可以完全丟棄的——真正核心的是一套與傳統(tǒng)Windows圖形界面設(shè)計(jì)完全不同的理念。關(guān)于這套設(shè)計(jì)理念,有一套叫做“人本界面”的設(shè)計(jì)方法論作為支撐,感興趣的小伙伴可以在豆瓣上搜索同名的圖書(shū)。

就本文要討論的內(nèi)容來(lái)說(shuō),我們可以簡(jiǎn)單的關(guān)注以下的一些要點(diǎn):

  • 智能設(shè)備的界面強(qiáng)調(diào)“簡(jiǎn)潔”、并希望“讓用戶的注意力一次只集中在一件簡(jiǎn)單的事物上”。
基于這一原則,又派生出了如下的特點(diǎn):
  • 與Windows不同,智能設(shè)備的界面很少(或者極力避免)窗口重疊
  • 界面的基本單位不是“窗體(Window)”,而是以整個(gè)屏幕為基本單位的“面板(Panel)”
  • 每個(gè)面板的內(nèi)容都盡可能簡(jiǎn)單、通過(guò)留白的方式強(qiáng)調(diào)那些需要用戶注意的內(nèi)容;
  • 每個(gè)面板的功能都盡可能單一:
    • 一般避免在同一個(gè)面板中擠進(jìn)多個(gè)不太相關(guān)的功能;
    • 相關(guān)的內(nèi)容,如果能夠放得下,且美觀,則可以有主次的布置在同一個(gè)面板中以減少用戶切換面板帶來(lái)的不便;
    • 如果相關(guān)的內(nèi)容如果無(wú)法在同一個(gè)面板中展示,則一定會(huì)添加快捷方式方便用戶快速進(jìn)行面板的切換;
  • 面板間的切換方式以大家熟悉的PPT頁(yè)面切換方式類(lèi)似
    • 對(duì)滑動(dòng)切換來(lái)說(shuō),要么不做,要做就要“絲滑”(差不多30FPS),否則會(huì)給用戶帶來(lái)“卡頓”的不適感
    • 完全沒(méi)有動(dòng)畫(huà)的切換往往會(huì)給用戶“設(shè)備反應(yīng)迅速”的錯(cuò)覺(jué),對(duì)負(fù)擔(dān)不起高幀率的嵌入式設(shè)備來(lái)說(shuō),反而是最好的選擇

仔細(xì)回想一下,身邊的智能設(shè)備,是不是都基本滿足上述特點(diǎn)?——其實(shí)我們熟悉的手機(jī)和平板也是如此。


基于上述原則,我們甚至可以總結(jié)出一套簡(jiǎn)單有效的“嵌入式界面設(shè)計(jì)八股”:

  • 用戶界面分成三個(gè)部分:狀態(tài)面板、導(dǎo)航面板功能面板
  • 狀態(tài)面板又叫待機(jī)面板,用于顯示狀態(tài)信息(比如溫度、時(shí)間、產(chǎn)品Logo、產(chǎn)品當(dāng)前狀態(tài)等等)。
    • 通常在待機(jī)界面上按下任意鍵(或者進(jìn)行任意觸摸)進(jìn)入導(dǎo)航面板
    • 一般用戶超過(guò)一段時(shí)間沒(méi)有與界面進(jìn)行交互后會(huì)自動(dòng)進(jìn)入狀態(tài)面板,所以狀態(tài)面板有時(shí)候又叫待機(jī)面板
  • 導(dǎo)航面板:也就是大家常說(shuō)的菜單。
    • 一般導(dǎo)航面板以圖標(biāo)、列表或者按鈕的形式存在,
    • 一般避免超出屏幕范圍的內(nèi)容,最好做到讓用戶對(duì)所有選項(xiàng)“盡收眼底”
    • 導(dǎo)航面板可以通過(guò)子面板的形式實(shí)現(xiàn)多級(jí)菜單,從而簡(jiǎn)化開(kāi)發(fā)
  • 功能面板:實(shí)現(xiàn)具體功能的面板,一般由導(dǎo)航面板進(jìn)入
    • 每個(gè)面板的功能都盡可能單一,比如專(zhuān)門(mén)設(shè)置溫度、專(zhuān)門(mén)設(shè)置時(shí)間等等
    • 相關(guān)的導(dǎo)航面板之間可以通過(guò)類(lèi)似左右箭頭(或者底部導(dǎo)航快捷按鈕)的機(jī)制進(jìn)行快捷切換




【什么是場(chǎng)景(scene)】


“場(chǎng)景(scene)”是 arm-2d為“手?jǐn)]GUI”的用戶引入的一個(gè)概念,通過(guò)配套的“場(chǎng)景播放器(scene player)”,極大的簡(jiǎn)化了基于面板的界面開(kāi)發(fā)。
一般來(lái)說(shuō),一個(gè)簡(jiǎn)單的面板用一個(gè)場(chǎng)景就可以搞定;而稍微復(fù)雜點(diǎn)的面板則可以通過(guò)多個(gè)場(chǎng)景(以及基于狀態(tài)機(jī)的場(chǎng)景切換)來(lái)搞定——總的原則就是,無(wú)論多復(fù)雜的面板,都可以拆分成一個(gè)個(gè)簡(jiǎn)單的場(chǎng)景來(lái)分而治之。
也許你已經(jīng)注意到了:原本面板本身就已經(jīng)很簡(jiǎn)單了,那么所謂“復(fù)雜的面板”根據(jù)狀態(tài)機(jī)拆分成多個(gè)場(chǎng)景后是不是更加簡(jiǎn)單了?——是的,每個(gè)場(chǎng)景的功能都是極其單一和簡(jiǎn)單的——極大的簡(jiǎn)化了每個(gè)場(chǎng)景的實(shí)現(xiàn)難度。


舉個(gè)例子:有個(gè)面板的功能是設(shè)置溫度,當(dāng)超過(guò)某一特定值后,需要彈出一個(gè)窗口提醒用戶當(dāng)前設(shè)置值有某些注意事項(xiàng)。這樣的面板在設(shè)計(jì)時(shí)就可以拆分成兩個(gè)場(chǎng)景:1)一個(gè)正常的數(shù)值設(shè)置場(chǎng)景,實(shí)現(xiàn)一個(gè)類(lèi)似滑條的功能讓用戶設(shè)置溫度;2)一個(gè)專(zhuān)門(mén)的場(chǎng)景來(lái)提示用戶注意事項(xiàng)——通過(guò)這樣的安排,每個(gè)場(chǎng)景都可以非常單一。再比如:某個(gè)面板的用來(lái)設(shè)置多個(gè)相關(guān)的選項(xiàng),并且當(dāng)用戶開(kāi)啟某個(gè)開(kāi)關(guān)后,會(huì)出現(xiàn)一些隱藏選項(xiàng)(或者原本不可設(shè)置的選項(xiàng)變成可選)。此時(shí),就可以根據(jù)這個(gè)開(kāi)關(guān)的狀態(tài),引入兩個(gè)場(chǎng)景:一個(gè)對(duì)應(yīng)開(kāi)關(guān)關(guān)閉時(shí)的面板,一個(gè)對(duì)應(yīng)開(kāi)關(guān)開(kāi)啟時(shí)的面板——總之,面板拆的越細(xì)致,每個(gè)場(chǎng)景的設(shè)計(jì)就越簡(jiǎn)單。


【場(chǎng)景(scene)的數(shù)據(jù)結(jié)構(gòu)和構(gòu)成】


場(chǎng)景在 arm-2d 中以類(lèi) arm_2d_scene_t 來(lái)描述:
/*! * \brief a class for describing scenes which are the combination of a *        background and a foreground with a dirty-region-list support *  */typedef struct arm_2d_scene_t arm_2d_scene_t;struct arm_2d_scene_t { arm_2d_scene_t *ptNext; //!< next scene arm_2d_scene_player_t *ptPlayer; //!< points to the host scene player arm_2d_region_list_item_t *ptDirtyRegion; //!< dirty region list for the foreground  arm_2d_helper_draw_handler_t *fnBackground; //!< the function pointer for the background  arm_2d_helper_draw_handler_t *fnScene; //!< the function pointer for the foreground void (*fnOnBGStart)(arm_2d_scene_t *ptThis); //!< on-start-drawing-background event handler void (*fnOnBGComplete)(arm_2d_scene_t *ptThis); //!< on-complete-drawing-background event handler void (*fnOnFrameStart)(arm_2d_scene_t *ptThis); //!< on-frame-start event handler void (*fnOnFrameCPL)(arm_2d_scene_t *ptThis); //!< on-frame-complete event handler  /*! * \note We use fnDepose to free the resources */ void (*fnDepose)(arm_2d_scene_t *ptThis); //!< on-scene-depose event handler struct { uint8_t bOnSwitchingIgnoreBG    : 1; //!< ignore background during switching period uint8_t bOnSwitchingIgnoreScene : 1; //!< ignore forground during switching period };};


其數(shù)據(jù)結(jié)構(gòu)并不復(fù)雜。



數(shù)據(jù)結(jié)構(gòu)的主體是這兩個(gè)指針:

  • fnScene:指向一個(gè)由用戶提供的繪圖函數(shù):

    • 繪制一個(gè)場(chǎng)景中所有的內(nèi)容;或者

    • 當(dāng)場(chǎng)景中存在“不會(huì)變化且不會(huì)被覆蓋的背景”和“少數(shù)”內(nèi)容會(huì)發(fā)生變化的前景時(shí),專(zhuān)門(mén)用于繪制前景——此時(shí)就需要通過(guò)ptDirtyRegion來(lái)指向描述前景變化區(qū)域的臟矩陣(Dirty Region List)。


  • fnBackground:指向一個(gè)由用戶提供的繪圖函數(shù),專(zhuān)門(mén)繪制一個(gè)場(chǎng)景中那些“只需要繪制一次”且“未來(lái)不會(huì)被前景覆蓋或者變化”的內(nèi)容,最典型的就是繪制場(chǎng)景中的背景圖片;


需要特別說(shuō)明的是:

  • fnBackground 只會(huì)在繪制每個(gè)場(chǎng)景的第一幀時(shí)調(diào)用;

  • 隨后的每一幀就只會(huì)調(diào)用 fnScene;

  • fnBackground 會(huì)繪制整個(gè)屏幕;

  • 臟矩陣(ptDirtyRegion)只對(duì) fnScene 有效;

  • 當(dāng)ptDirtyRegion 為 NULL時(shí),fnScene也是繪制整個(gè)屏幕

    • 這意味著,當(dāng) ptDirtyRegionNULL時(shí),fnBackground 繪制的內(nèi)容會(huì) 100% 被覆蓋掉——也就是說(shuō)完全沒(méi)用。這意味著:

    • 當(dāng)且僅當(dāng)我們指定了有效的臟矩陣時(shí),fnBackground 才是實(shí)際有意義的


如果你對(duì)“背景”和“前景”的分工感到似懂非懂,不妨看下面這個(gè)例子:



在這個(gè)場(chǎng)景中:

  • 作為背景的狗頭實(shí)際上不會(huì)發(fā)生變化,因此我們只需在 fnBackground 所指向的繪圖函數(shù)中繪制即可;

  • 動(dòng)態(tài)進(jìn)度條由于其內(nèi)容一直在變化,因此需要在 fnScene所指向的繪圖函數(shù)中“配合臟矩陣”進(jìn)行重復(fù)繪制。


為了方便應(yīng)用開(kāi)發(fā),arm_2d_scene_t 提供了一系列事件處理程序接口(回調(diào)函數(shù)),它們與背景、場(chǎng)景的繪制關(guān)系如下:


可以看到,這里的事件處理順序并不復(fù)雜,大家可以根據(jù)實(shí)際的應(yīng)用需求各取所需。

【場(chǎng)景播放器(scene player)的本質(zhì)是什么】
場(chǎng)景播放器的本質(zhì)是一個(gè)針對(duì)場(chǎng)景(scene)的隊(duì)列(FIFO):


  • 用戶可以預(yù)先生成多個(gè)場(chǎng)景,并通過(guò)函數(shù)arm_2d_scene_player_append_scenes壓入隊(duì)列中;
  • 隊(duì)列的頭部就是當(dāng)前生效的場(chǎng)景;
  • 用戶可以在任意時(shí)刻通過(guò)函數(shù)arm_2d_scene_player_switch_to_next_scene來(lái)安全的觸發(fā)場(chǎng)景切換,
    • 所謂的場(chǎng)景切換就是丟棄隊(duì)列當(dāng)前的頭部場(chǎng)景——換成下一個(gè);
  • 場(chǎng)景切換后,被丟棄的場(chǎng)景會(huì)調(diào)用 fnDepose ,用戶可以利用這個(gè)函數(shù)為對(duì)應(yīng)場(chǎng)景“擦屁股”
    • 比如,假設(shè)一個(gè)場(chǎng)景(arm_2d_scene_t)對(duì)象本身就是動(dòng)態(tài)分配的(從 malloc中分配),那么就可以通過(guò) fnDepose 方法來(lái)將內(nèi)存釋放掉(比如調(diào)用 free函數(shù))。
  • 場(chǎng)景播放器提供了 arm_2d_scene_player_flush_fifo 方法,它會(huì)清空整個(gè)隊(duì)列。
    • 被清空出去的場(chǎng)景都會(huì)被依次調(diào)用 fnDepose,因此不用擔(dān)心內(nèi)存泄露的問(wèn)題。
  • 場(chǎng)景切換是支持特效的,比如:淡入淡出、滑動(dòng)和擦除等等


【用場(chǎng)景開(kāi)發(fā)也太簡(jiǎn)單了8!】


前面洋洋灑灑的做了這么多理論鋪墊,也許會(huì)讓你對(duì) scene 的使用產(chǎn)生了“非常復(fù)雜”的錯(cuò)覺(jué)或者擔(dān)憂,但實(shí)際情況卻相反:借助cmsis-packRTE的幫助,創(chuàng)建 scene 幾乎只要點(diǎn)幾下鼠標(biāo)就可以搞定,而且立即就可以使用。
假設(shè)你已經(jīng)根據(jù)《【喂到嘴邊了的模塊】準(zhǔn)備徒手?jǐn)]GUI?用Arm-2D三分鐘就夠了》的描述,完成了 arm-2d 的部署,并且成功的加入了一個(gè) Display Adapter,此時(shí)我們應(yīng)該能看到這樣的效果:


此時(shí),打開(kāi) RTE,展開(kāi)Acceleration后在Arm-2D Helper中找到 Scene


如果你的界面中找不到 Scene,說(shuō)明你的 arm-2d cmsis-pack 版本較老,可以關(guān)注公眾號(hào)【裸機(jī)思維】后,發(fā)送關(guān)鍵字 arm-2d 后獲取最新版本的網(wǎng)盤(pán)鏈接。

Scene的右邊,我們可以通過(guò)“增加數(shù)值”的方式向工程中添加指定數(shù)量的場(chǎng)景。單擊確定后,對(duì)應(yīng)數(shù)量的場(chǎng)景模板會(huì)加入到工程管理器中:


這里的 arm_2d_scene_0.harm_2d_scene_0.c 分別對(duì)應(yīng)我們新加入的場(chǎng)景的頭文件和源代碼。


打開(kāi) main.c,加入對(duì)場(chǎng)景的頭文件引用:
#include "arm_2d_scene_0.h"

其實(shí),所謂的 Display Adapter 就是場(chǎng)景播放器(arm_2d_scene_player_t):

ARM_NOINITexternarm_2d_scene_player_t DISP0_ADAPTER;

在初始化完 Display Adapter 后,我們調(diào)用場(chǎng)景的初始化函數(shù)arm_2d_scene0_init()——將它們加入指定的場(chǎng)景播放器隊(duì)列中:

#include "arm_2d_scene_0.h"...int main (void) { arm_irq_safe { arm_2d_init(); }   disp_adapter0_init();  arm_2d_scene0_init(&DISP0_ADAPTER);  while(1) { disp_adapter0_task(); }  }

調(diào)用函數(shù) arm_2d_scene_player_switch_to_next_scene() 來(lái)切換到我們新加入的場(chǎng)景中:

#include "arm_2d_scene_0.h"...int main (void) { arm_irq_safe { arm_2d_init(); }   disp_adapter0_init();  arm_2d_scene0_init(&DISP0_ADAPTER); arm_2d_scene_player_switch_to_next_scene(&DISP0_ADAPTER);  while(1) { disp_adapter0_task(); }  }


為了方便觀察效果,不妨設(shè)置一個(gè)場(chǎng)景切換效果:


#include "arm_2d_scene_0.h"...int main (void) { arm_irq_safe { arm_2d_init(); }   disp_adapter0_init();  /* 初始化場(chǎng)景 scene0,并將其加入到場(chǎng)景播放器 DISP0_ADAPTER 中 */ arm_2d_scene0_init(&DISP0_ADAPTER);  /* 設(shè)置切換特效為 淡入淡出(白色) */ arm_2d_scene_player_set_switching_mode(  &DISP0_ADAPTER, ARM_2D_SCENE_SWITCH_MODE_FADE_WHITE); /* 設(shè)置切換持續(xù)時(shí)間為 3000ms */ arm_2d_scene_player_set_switching_period( &DISP0_ADAPTER,  3000);  /* 申請(qǐng)切換到新加入的場(chǎng)景中 */ arm_2d_scene_player_switch_to_next_scene(&DISP0_ADAPTER);  while(1) { disp_adapter0_task(); }  }  

編譯后運(yùn)行,可以看到類(lèi)似如下的效果:



可以看到,場(chǎng)景播放器從默認(rèn)的“轉(zhuǎn)圈圈”界面以“漸明漸暗”的形式切換到了我們的新場(chǎng)景 scene0 中。



細(xì)心的小伙伴可能很快就注意到了一個(gè)奇怪的地方:為啥很快 scene0 又消失在白屏中了呢?要解答這一疑問(wèn)不妨打開(kāi)
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉