nesC 1.1 語言參考手冊(2)

來源:互聯網
上載者:User
7 配置配置是通過串連、配線,建立與其他組件的串連:configuration-implementation:implementation { component-listopt connection-list }組件列表列出用來建立這一個結構的組件,串連列表指明各組件之間,以及與結構說明之間是怎樣裝配在一起的。在這一節的其餘部分中,我們調用來自結構的外部的規格元素, 和來自結構的內在的成份之一的規格元素。7.1 包含組件組件列表列出用來建立這一個結構的組件。在結構裡面這些組件可隨意的重新命名,使用共同板型規格元素,或簡單的改變組件結構從而避免名稱衝突。(以避免必須改變更配置線)為組件選擇的名字屬於成份的實現域。component-list:componentscomponent-list componentscomponents:components component-line ;component-line:renamed-identifiercomponent-line , renamed-identifierrenamed-identifier:identifieridentifier as identifier如果二個組件使用as給出相同的名字,則會發生編譯時間錯誤(舉例來說., componentsX, Y as X)。只有一個個別的例子:如果組件 K 被用於二不同的結構 ( 或甚至兩次用於相同的結構裡面), 在程式中仍然只有 K(及它的變數) 的唯一執行個體。7.2 配線配線用於串連規格元素 (介面,指令,事件)。本節和下一節(第 7.3 節) 定義配線的文法和編譯-時間規則。第 7.4 節詳細說明程式配線聲明是如何指出在每個調用和訊號表達中哪個函數被調用。connection-list:connectionconnection-list connectionconnection:endpoint = endpointendpoint -> endpointendpoint <- endpointendpoint:identifier-pathidentifier-path [ argument-expression-list ]identifier-path:identifieridentifier-path . identifier配線陳述串連二個端點。每個端點的標識符路徑指明一個規格要素。自Variant 運算式列表可選的指出介面參數值。如果端點的規格要素是參數化的,而端點又沒有參數值,那麼我們說該端點是參數化的。如果一個端點有參數值,而下面的任一事件成立時,就會產生一個編譯時間錯誤:     三數值不全是常量運算式.     端點的規格元素不是參數化的.     參數個數比規格要素中限定的三數個數多 ( 或少)      三數值不在規格元素限定的三數類型範圍中。如果端點的標識符路徑不是以下三種形式之一,就會產生一個編譯時間錯誤:      X, 此處X命名一種外部的規格元素.       K.X,此處K 是組件列表中的一個組件,而X是K 的規格元素。K ,此處K是組件列表中的一些組件名。這種形式用在固定的串連中,將在第 7.3 節中討論。注意,當三數值指定時這種形式不能夠使用。nesC 有三種配線陳述:       endpoint1=endpoint2:( 賦值配線) 任何串連包括一外部規格元素。這些有效地使兩規格元素相等。設S1是endpoint1的規格要素,S2是endpoint2的規格要素。下面兩個條件之一必須滿足,否則就會產生編譯時間錯誤:– S1 是內部的, S2 是外部的 (反之亦然) ,並且 S1 和 S2都是被提供或都是被使用– S1 和 S2 都是外部的,而且一個被提供,而另一個被使用.endpoint1->endpoint2:( 聯編配線) 一個串連包括二種內在的規格元素。.聯編配線總是連結一由endpoint1指定的使用規格元素到一endpoint2指定的提供規格元素。如果這兩個條件不能滿足, 就會發生編譯-時間錯誤.。     endpoint1<- endpoint2 與endpoint2 -> endpoint1是等價的。在配線的所有三種類型中,兩被指定的規格元素必須是一致的,就是說., 它們必須都是指令,或都是事件, 或都是介面執行個體. 同時, 如果它們是指令(或事件),則它們必須有相同的函數名 如果他們是介面執行個體,它們必須有相同的介面類型。他們一定是有相同的介面類型的. 如果這些條件不能滿足, 就會發生編譯-時間錯誤.。如果一個端點是參數化的,則另一個必須也是而且必須有相同的三數類型;否則就會發生編譯-時間錯誤.。相同的規格元素可以被多次串連,舉例來說.,:configuration C {provides interface X;} implementation {components C1, C2;X = C1.X;X = C2.X;}在這個例子中,當介面X中的命令被調用時,多次的配線將會導致介面X的事件的多重訊號 ("扇入"),以及多個函數的執行("扇-出")。注意,當二個結構獨立地連接相同介面的時候,多重配線也能發生,舉例來說.:configuration C { }                configuration D { }implementation {                  implementation {components C1, C2;                components C3, C2;C1.Y -> C2.Y;                    C3.Y -> C2.Y;}                                }所有的外部規格元素必須配線,否則發生編譯-時間錯誤. 可是,內部的規格元素可以不串連 (它們可能在另外一個結構中配線,或者如果模組有適當的預設事件或指令實現,他們可以不配線).7.3 隱含串連隱含串連可以寫成K1 <- K2.X 或K1.X <- K2 (=和->是等價的). 該用法通過規格元素K1 (不妨K2)來引用規格元素 Y,因此K1.Y <- K2.X (不妨 K1.X <- K2.Y )形成一個合法連接。如果能正確的引用Y,則串連建立,否則發生編譯-時間錯誤。舉例來說:module M1 {                          module M2 {provides interface StdControl;             uses interface StdControl as SC;} ...                                  } ...configuration C { }implementation {interface X {                           module M {command int f();                        provides interface X as P;event void g(int x);                      uses interface X as U;}                                         provides command void h();} implementation { ... }configuration C {provides interface X;provides command void h2();}implementation {components M;X = M.P;M.U -> M.P;h2 = M.h;}圖 1: 簡單的配線例子components M1, M2;M2.SC -> M1;}M2.SC -> M1 這一行與M2.SC -> M1.StdControl. 是等價的。7.4 配線語義我們首先撇開參數化介面討論配線語義. 7.4.1 節將討論參數化介面。最後,第 7.4.2 節敘述整體上而言,程式配線聲明上的要求。我們將會用到圖1中的簡單程式作為我們啟動並執行例子。我們根據中間函數定義配線的意義。每個組件的每個指令或事件都有中間函數. 舉例來說,在圖 1 中,模組M 有中間函數 IM.P.f , IM.P.g , IM.U.f , IM.U.g , IM.h. 在例子中,我們以其組件,任意介面執行個體名,及函數名為基礎命名中間函數。中間函數不是使用就是提供。每個中間函數接受與組件說明中相應指令或事件相同的自變數。中間函數體I是調用(執行系列)其它中間函數的列表。I 通過程式配線說明串連到其它中間函數 。I接受的自變數不變的經過被調用的中間函數.I 返回結果清單,(列表元素類型是相應指令或事件返回給I的結果類型),列表通過串連調用中間函數返回結果構成。返回空值的中間函數適合不相串連的指令或事件;返回兩個或以上值的中間函數適合“扇出”。nesC允許在沒有直接中間函數的情況下編譯,所以本節中描述的行為沒有運行開銷,實際的函數調用需要參數化的指令或事件。 中間函數和結構 一個結構的配線說明指定中間函數體。我們首先擴充配線說明到中間函數而不限於規格元素,並取消配線說明中= 和->的區別。我們用 I1<-> I2 表示中間函數I1 和I2之間的連結。舉例來說,圖 1中的結構C 敘述了下列中間函數串連:IC.X.f<-> IM.P.f     IM.U.f<-> IM.P.f     IC.h2<->IM.hIC.X.g<-> IM.P.g     IM.U.g<->IM.P.g在結構 C 的串連I1 <-> I2中,二個中間函數之一是被調用的,另一個是調用者。如果下列任一條件成立(我們使用內部或外部的用辭作規格說明並不妨礙結構 C包含串連),則I1(同樣地,I2)是被調用的:       如果 I1 符合一件被提供指令或事件的內部規格元素.       如果 I1 符合一件被使用指令或事件的外部規格元素.    如果 I1 符合一個介面執行個體X 的指令,而X是內部的且被提供或外部的且被使用的規格元素.     如果 I1 符合一個介面執行個體X 的事件,而X是外部的且被提供或內部的且被使用的規格元素.如果這些情況沒有一個成立,則I1 調用者。7.2 節的配線規則確保一個串連 I1<->I2 不會同時串連二個調用者或二個被調用者。圖1的結構 C 中,IC.X.f , IC.h2 , IM.P.g,IM.U.f 是調用者而 IC.X.g , IM.P.f , IM.U.g,IM.h 是被調用者。如此C的串連說明IC.X.f 調用IM.P.f,IM.P.g調用IC.X.g,等等。 中間函數和模組 模組中的C代碼調用中間函數,或被中間函數調用。模組M中提供指令或事件a的中間函數I 包含一個單獨調用以運行M中的a。其結果是一個單獨的調用返回列表。運算式call a(e1, . . . , en)性質如下:     自變數e1, . . . , en 被賦值為v1, . . . , vn.。      a對應的中間函數被以自變數v1, . . . , vn調用,返回結果清單L.      如果 L=(w)( 一個獨立列表),調用的返回結果就是 w.如果 L=(w1,w2, . . . ,wm) (二或更多的元素),調用的結果仰賴於a的傳回型別t。如果t=void,則結果是void。否則,t 一定有一聯合函數c( 第 10.3節示範聯合函數是如何等位型別的),否則發生編譯-時間錯誤。聯合函數接受類型t 的兩個值並且返回一個類型t的結果。該調用的結果是c(w1, c(w2, . . . , c(wm&S722;1,wm))) ( 注意L中元素次序是任意的).list of int IM.P.f() {              list of void IM.P.g(int x) {  return list(M.P.f());              list of int r1 = IC.X.g(x);}                               list of int r1 = IM.U.g(x);return list concat(r1, r2);}list of int IM.U.f() {             list of void IM.U.g(int x) { return IM.P.f();                  return list(M.U.g(x));}                           }list of int IC.X.f() {              list of void IC.X.g(int x) { return IM.P.f();                    return empty list;}                            }list of void IC.h2() {              list of void IM.h() {return IM.h();                    return list(M.h());}                            }圖 2: 圖1的中間函數         如果 L 為空白則預設以v1, . . . , vn,為自變數調用執行a,並返回該調用結果。第 7.4.2 節表明如果L為空白且a沒有預設實現則會發生一編譯- 時間錯誤。訊號運算式的規則是一樣的。 中間函數舉例 圖 2使用類C的文法示範了圖 1中組件產生的中間函數,其中list(x)產生一個包含X的獨立列表,空列表是表示含0個元素的列表的常量,串連列表如鎖鏈般串連兩個列表。對M.P.f, M.U.g, M.h的調用,調用模組M中實現的指令和事件(未給出)。7.4.1 配線和參數化函數如果組件K的一條指令或事件a帶有類型t1, . . . ,tn的介面三數,則對每一數組(v1 : t1, . . . , vn :tn)存在一個中間函數Ia,v1,...,vn 。在模組中,如果中間函數Iv1,...,vn符合參數化的提供指令(或事件)a,則Iv1,...,vn中對a的實現的調用將傳遞v1, . . . , vn作為a的介面參數。下面是對錶達式call _[e01, . . . , e0m](e1, . . . , en)討論:       自變數e1, . . . , en被賦值為 v1, . . . , vn。       自變數e01, . . . , e0m被賦值為v01 , . . . , v0m。       v0i 對應ti 類型, 這裡t i 是a的第i個介面三數的類型。       a對應的中間函數Iv01 ,...,v0m被以參數v1, . . . , vn,調用,返回列表L。       如果 L 有一個或更多的元素, 在非參數化的情形下產生調用結果      如果 L 為空白,a的預設實現會被以自變數v1, . . . , vn,,以介面參數值v01 , . . . , v0m調用,且返回該調用的結果。7.4.2節表明如果L為空白且a沒有預設實現,則會產生編譯-時間錯誤。訊號運算式的規則是一樣的.配線說明中的一個端點關係到一參數化規格元素時,有二種情形:      端點指定三數值 v1, . . . , vn。若端點符合指令或事件 a1, . . . ,am ,則相應的中間函數為Ia1,v1,...,vn,. . . , Iam,v1,...,vn且配線方式不變。       端點未指定三數值. 在這情況下,配線說明的兩個端點都對應相同介面參數類型t1, . . . ,tn.的參數化規格元素。如果一個端點對應指令或事件 a1, . . . , am 而另一端點對應指令或事件 β1, . . . , βm,則對所有的1<=i<= m和所有的數組(w1 : t1, . . . ,wn : tn)有串連Iai,w1,...,wn<-> Iβi,w1,...,wn (就是說., 端點是為所有對應的三數值串連的).。7.4.2 應用級的需求一個應用的配線說明必須滿足兩個需求, 否則就會發生編譯時間錯誤:       沒有只包含中間函數的無限迴圈.      在應用模組中的每個call a ( 或signal a)運算式中:–如果調用是非參數化的:如果調用返回空的結果清單,則a一定有預設實現 (結果清單中元素個數只仰賴於配線)。–如果調用是參數化的:如果a的介面三數的任何替代值都返回空結果清單,則a必定有預設的實現 (給定參數值數組的返回結果清單中元素數目只仰賴於配線)。注意這種情況不考慮用來在調用點敘述介面參數值的表達。該調用的特色是包含在幾個指令執行間的運行時選擇——這是中間函數唯一的一處運行時開銷 8 nesC 的協作nesC採用由一旦運行直至完成作業(代表性的即時運算)和硬體非同步觸發中斷控制構成的運行模型。編譯器依靠使用者提供的事件控制代碼和原語特徵來識別中斷源 (見10.3節)。nesC發送器能以任意次序運行作業,但是必須服從一旦運行直至完成規則 (標準的TinyOS發送器遵從FIFO(先進先出)策略).因為作業不能獨佔且是一旦運行直至完成的,所以它們是原子的互不妨礙的,但能夠被中斷。由於這種並行運行模型,在程式共用的狀態下特殊資料競爭,導致nesC 程式狀態是不穩定的。比如,它的全域和模組內變數 (nesC不含動態儲存裝置配置). 為避免競爭,要麼只在作業內部訪問共用狀態,要麼只在原子的聲明內部訪問。編譯時間,nesC 編譯器會報告潛在的資料競爭。形式上, nesC 程式碼分為二個部份:同步碼 sync (SC):僅僅在作業內部可達的編碼 (函數,指令,事件,作業)非同步碼 async (AC):至少一個中斷源可達的代碼.雖然非搶佔消除作業之間的資料競爭, 但是在SC 和 AC,以及AC 和 AC 之間仍然有潛在的競爭。通常,任何從 AC可達的共用狀態更新都是一個潛在的資料競爭. nesC 啟動並執行基本常量是:無競爭常量:任何共用狀態更新要麼僅同步碼可達,要麼僅發生在原子陳述內部. 只要所有對函數f 的調用是在原子陳述內部的,我們就認為對f 的調用是在原子陳述內部的。這可能引入一種編譯器不能夠發現的競爭情況,但它一定是跨越多個原子陳述或作業的,並且是使用中間儲存變數的。nesC 可能報告實際上不會發生的資料競爭,舉例來說., 如果所有的通路都被其他變數上的守衛保護。在這種情況下,為避免多於的訊息,程式會用注釋儲存類型說明注釋一個變數v,從而忽略所有關於v的資料競爭警告。注釋關鍵字應謹慎使用。 對任何非同步碼的且沒有聲明非同步指令或事件,nesC 會報告編譯- 時間錯誤。這確保那些不安全的代碼不會在中斷時無意中被調用。 9 nesC 應用程式一個 nesC應用程式有三個部份。:一連串的 C 聲明和定義,一組介面類型,和一組組件。nesC 應用程式命名環境構造如下:   最外層的全域命名環境,包含三個命名域: 一個 C 變數,一個用於C聲明和定義的C 標籤命名域,和一個用於組件和介面類型的組件和介面類型命名域。    通常,C聲明和定義可以在全域命名環境內部引入自己的嵌套命名域(用於函式宣告和定義的函數內部程式碼片段,等等)。    每個介面類型引入一個命名域,用於儲存介面的指令或事件。這種命名域是嵌套於全域命名環境的,所以指令和事件定義能影響全域命名環境中的C類型和標籤定義。     每個組件引入二個新命名域。規格命名域,嵌套於全域命名環境,包含一變數命名域用於存放組件規格元素。實現命名域, 嵌套於規格命名域,包含一個變數和一個標籤命名域。對於結構,作用範圍變數命名域包含組件用以引用其包含組件的名字 (7.1節). 對於模組,作用範圍儲存作業,以及模組體中的C聲明和定義。這些聲明,及其它可能引入自己的嵌套在作用範圍內的命名域 (比如函數體,程式碼片段等等). 由於這種命名域的嵌套結構,模組中的代碼可以訪問全域命名環境中的C聲明和定義,但是不能訪問其他組件中的任何聲明或定義.。構成一個nesC應用程式的C聲明和定義,介面類型和組件由一個隨選的裝載程式決定。nesC 編譯器的輸入是一個單獨的組件K。nesC 編譯器首先裝載C檔案 (第 9.1 節),然後裝載組件K(9.2節)。程式所有代碼的裝載是裝載這兩個檔案的過程的一部分。nesC 編譯器假定所有對函數,指令及事件的調用不以自然的屬性 (第 10.3 節) 都發生被裝載的代碼中(例如., 沒有對非自然的函數 " 看不見的 " 調用)。在裝載檔案預先處理的時候,nesC 定義NESC 符號,用於識別nesC 語言和編譯器版本的數字 XYZ。對於nesC 1.1, XYZ 至少為110。裝載C 檔案,nesC組件及介面類型的過程包括定位對應的資源檔。檔案定位的機制不是本參考手冊中所要討論的。要詳細瞭解通用編譯器是如何作業的,請閱讀《the ncc man page.》9.1 裝載 C檔案X如果 X 已經被裝載,就不用再做什麼。否則, 就要定位並預先處理檔案 X.h。C宏定義 ( 由 # define和 #undef) 的改變會影響到所有的後面的檔案預先處理。來自被預先處理的檔案X.h的 C聲明和定義會進入C全域命名環境,因此對所有的後來的 C檔案加工,介面類型和組件是有影響的。5舉例來說,現在的 nesC 編譯器使用這些資訊除去無法訪問的代碼.6NESC 符號不被在 nesC 的較早版本中定義.9.2 裝載組件K如果K已經被裝載,就不用再做什麼。否則, 就要定位並預先處理檔案 X.nc。對C宏定義( 由 # define和 #undef)的變化被忽略。使用下面的文法分析預先處理檔案:nesC-file:includes-listopt interfaceincludes-listopt moduleincludes-listopt configurationincludes-list:includesincludes-list includesincludes:includes identifier-list ;如果 X.nc沒有定義模組K 或結構 K,將報告編譯-時間錯誤。否則,所有的包含列表指定的C檔案都將被裝載 (9.1節)。然後,組件說明中用到的所有介面類型都將被裝載(9.3節)。接著,處理組件說明(第5節). 如果 K 是一個結構, K 指定的 (第 7.1 節) 的所有組件被裝載 (9.2節)。最後,K的實現被處理 (第6節和第7節)。9.3 載入介面類型I如果I已經被裝載,就不用再做什麼。否則, 就要定位並預先處理檔案 X.nc。對C宏定義( 由 # define和 #undef)的變化被忽略。預先處理檔案同上面的nesC-檔案一樣分析。如果 X.nc沒有定義介面I,將報告編譯-時間錯誤。否則,所有的包含列表指定的C檔案都將被裝載 (9.1節)。接著,處理I的定義(第4節).。作為組件或介面包含C 檔案的例子,介面類型Bar可能包含用於定義Bar中使用的類型的C檔案BarTypes.h:Bar.nc:                                  BarTypes.h:includes BarTypes;                        typedef struct {interface Bar {                                int x;command result_t bar(BarType arg1);           double y;}                                      } BarType;介面Bar的定義能參考Bar類型, 同樣任何使用和提供介面Bar組件也能(裝載任何這些組件說明或實現之前,都要先裝載介面Bar,自然還有BarTypes.h) 10 多樣性10.1沒有自變數的函數的C聲明的舊風格沒有自變數的 nesC函數使用()聲明, 而不是 (void)。後者的用法將報告編譯-時間錯誤.。舊式的C聲明(用())和函數定義(在自變數之後指定參數列表)在介面和組件中是不允許的(會引起編譯-時間錯誤)。注意這些變化都不用於C檔案(以便現有的.h 檔案能被不變的使用).10.2 // 注釋nesC 允許C,介面類型和組件檔案中的 //注釋 。10.3 屬性nesC使用gcc的屬性文法聲明函數的一些屬性,變數及類型。這些屬性可以放置在聲明(在聲明符之後) 或函數定義.(在三數列表之後)上。 x 的屬性是全部x 的聲明和定義.上的所有屬性的集合。nesC 的屬性文法是:init-declarator-list: alsoinit-declarator attributesinit-declarator-list , init-declarator attributesfunction-definition: alsodeclaration-specifiersopt declarator attributesdeclaration-listoptcompound-statementattributes:attributeattributes attributeattribute:attribute ( ( attribute-list ) )attribute-list:single-attributeattribute-list , single-attributesingle-attribute:identifieridentifier ( argument-expression-list )gcc不允許函數定義中參數列表後面的屬性.nesC 支援五種屬性:     C:這一屬性用於在一個模組的頂層作為C 聲明或定義 d( 它被所有其他聲明忽略). 這指明d應該出現在全域範圍,而不是模組的組件範圍。這允許在C代碼中使用(舉例來說,如果它是一個函數,則可被調用)d。       自然的: 這一個屬性可用於任何函數 f (在模組或 C代碼中)。.這指出對f的調用在原始碼中是不可見的。典型地,函數自然地被中斷源 ,和C主函數調用。第9節討論 nesC 編譯器在編譯期間如何使用自然的屬性。       事件控制代碼: 這一個屬性可用於任何函數 f (在模組或 C代碼中)。它指出f 是一個中斷處理函數, 自動被硬體調用。這意味著f 既是自然的又是非同步碼 (AC)。     原子的事件控制代碼: 這一個屬性可用於任何函數 f (在模組或 C代碼中)。它指出f 是一個中斷處理函數, 自動被硬體調用,屏蔽中斷的運行。這意味著f 既是自然的又是非同步碼 (AC)。而且,f 運行時好像被封裝進一個原子的陳述。    聯合 (fnname): 這一屬性為類型定義聲明中一個類型指定聯合函數。聯合函數指定該如何聯合調用一指令或事件而"扇出“返回的多個結果。舉例來說:typedef uint8_t result_t __attribute__((combine(rcombine)));result_t rcombine(result_t r1, result_t r2){return r1 == FAIL ? FAIL : r2;}當聯合指令(或事件)傳回型別是t 時,敘述邏輯-相似的行為。詳細的語義見第 7.4 節。如果類型 t 的聯合函數c沒有類型t c(t,t),就會發生編譯時間錯誤。使用屬性的例子:在檔案 RealMain.td 中:module RealMain { ... }implementation {int main(int argc, char **argv) __attribute__((C, spontaneous)) {}}這個例子表明主函數實際上應該出現在 C全域命名空間 (C),所以連接器能找它。它還表明即使在程式任何地方都沒有函數調用主函數,主函數同樣能夠被調用(自然的)。10.4 編譯-時間常量函數nesC有新類型的常量運算式:常量函數。常量函數在語言裡面定義的函數,編譯時間當作一個常數.nesC 現在有二種常量函數:      unsigned int unique(char *identifier)傳回值:如果程式包含n個有相同標示字串的對unique的調用,每個調用返回一個0~n-1之間的不帶正負號的整數。例如有10個unique("abc"),則每一個unique("abc")的結果是一個1~9之間的數字,而且,不會相重複。故10個unique("abc")其實就是進行了一個從0到9的編號。使用unique的目的是為了把一個唯一整數傳遞給參數化介面的執行個體,以便一個組件只要提供一個參數化介面就能唯一地識別串連到那個介面的各種不同組件。      unsigned int uniqueCount(char *identifier)傳回值:如果程式包含 n個有相同標示字串的對unique的調用,每個調用都返回n(既unique在程式中出現的個數)。使用uniqueCount的目的是為了度量數組(或其他的資料結構)的大小,這些數組使用unique返回的數來進行索引的。舉例來說, 一個定時器服務是通過一個參數化介面來識別它的客戶的(每個獨立的定時器由此而來),使用unique可以使用uniqueCount來分配正確個數的定時器資料結構。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.