NESC 1.1 Language Reference Manual (2)

Source: Internet
Author: User
7. ConfigurationThe configuration is to establish a connection with other components through connection and wiring: configuration-implementation: Implementation {component-listopt connection-list} component list to list the components used to establish this structure, the connection List specifies the components and how they are assembled with the structure description. In the rest of this section, we call the specification elements from the external structure and from one of the internal components of the structure. 7.1 contains the component list to list the components used to establish this structure. You can rename these components at will in the structure, use a common shape element, or simply change the component structure to avoid name conflicts. (To avoid changing the wiring) the name selected for the component belongs to the component implementation domain. Component-list: componentscomponent-list componentscomponents: Components component-line; component-line: renamed-identifiercomponent-line, renamed-identifierrenamed-identifier: identifieridentifier as Identifier if the two components use the same name as the as component, a compilation time error occurs (for example ., componentsx, y as X ). There are only one example: If component K is used in two different structures (or even twice in the same structure), there is still only K (and its variables) in the program). 7.2 wiring and wiring are used to connect specification elements (interfaces, commands, and events ). This and next sections (section 7.3) define the wiring syntax and compile-time rules. Section 7.4 details how the program wiring statement specifies which function is called in each call and signal expression. Connection-list: connectionconnection-list connectionconnection: endpoint = endpointendpoint-> endpointendpoint <-endpointendpoint: Identifier-pathidentifier-path [argument-expression-list] Identifier-path: identifieridentifier-path. the identifier wiring statement connects two endpoints. The identifier path of each endpoint specifies a specification element. The list of independent variable expressions can indicate the interface parameter values. If the specification element of an endpoint is parameterized and the endpoint does not have a parameter value, the endpoint is parameterized. If an endpoint has a parameter value and any of the following events is created immediately, a compilation time error occurs: The parameter values are not all constant expressions. the specification element of the endpoint is not parameterized. the parameter quantity is more (or less) than the parameter quantity specified in the Specification element. The parameter quantity is not in the parameter quantity range specified by the specification element. If the path of the endpoint identifier is not one of the following three forms, a compilation time error occurs: X. Here, X is named as an external specification element. k. x. K is a component in the component list, and X is a type element of K. K. Here K is some component names in the component list. This form is used in a fixed connection and will be discussed in section 7.3. Note that this form cannot be used when the parameter value is specified. NESC has three wiring statements: endpoint1 = endpoint2: (assign a value to the wiring) Any connection includes an external specification element. These effectively make the two specification elements equal. Set S1 as the specification element of endpoint1, and S2 as the specification element of endpoint2. One of the following two conditions must be met; otherwise, a compilation time error occurs:-S1 is internal, S2 is external (and vice versa ), in addition, S1 and S2 are both provided or used-S1 and S2 are both external and one is provided, while the other is used. endpoint1-> endpoint2: (Combined Wiring) a connection contains two internal specification elements .. The associated wiring always links a specification element specified by endpoint1 to a specification element specified by endpoint2. If these two conditions cannot be met, a compilation-time error occurs .. Endpoint1 <-endpoint2 and endpoint2-> endpoint1 are equivalent. In all three types of wiring, the two specified specification elements must be consistent, that is ., they must all be commands, events, or interface instances. at the same time, if they are commands (or events), they must have the same function names. If they are interface instances, they must have the same interface type. They must have the same interface type. If these conditions cannot be met, a compilation-time error will occur .. If an endpoint is parameterized, the other endpoint must have the same parameter type. Otherwise, a compilation-time error occurs .. Elements of the same specification can be connected multiple times. For example .,: configuration c {provides interface X;} implementation {components C1, C2; X = c1.x; X = c2.x;} in this example, when the command in interface X is called, multiple wiring leads to multiple signals ("fan in") of interface X events and execution of multiple functions ("fan-out "). Note: When the two structures are independently connected to the same interface, multiple wiring can also happen, for example.: configuration c {} configuration d {} implementation {components C1, C2; components C3, C2; c1.y-> c2.y; c3.y-> c2.y ;}} all external specification elements must be wired; otherwise, a compilation-time error occurs. however, the internal specification elements can be retained (they may be wired in another structure, or they can be retained if the module has an appropriate default event or command implementation ). 7.3 implicit connections can be written as k1 <-k2.x or k1.x <-K2 (= and-> are equivalent ). this method uses the type element K1 (K2) to reference the type element Y. Therefore, k1.y <-k2.x (k1.x <-k2.y) forms a valid connection. If y can be correctly referenced, the connection is established. Otherwise, a compilation-time error occurs. For example, 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;} Figure 1: simple wiring example: Components M1, M2; m2. SC-> m1;} m2. SC-> m1 and m2. SC-> m1.stdcontrol. is equivalent. 7.4 wiring semantics we will first open the parameterized interface to discuss the wiring semantics. Section 7.4.1 will discuss the parameterized interface. Finally, section 7.4.2 describes the overall requirements of the program wiring statement. We will use the simple program shown in Figure 1 as an example. We define the meaning of the wiring according to the intermediate function. Each Command or event of each component has an intermediate function. for example, in Figure 1, module M has an intermediate function im. p. f, im. p. g, im. u. f, im. u. g, im. h. in this example, we use its component, any interface instance name, and function name as the base name of the intermediate function. Intermediate functions are provided either when used or not. Each intermediate function accepts the same independent variables as the corresponding commands or events in the component description. The intermediate function body I is a list of other intermediate functions called (Execution series. I connects to other intermediate functions through program Wiring instructions. I. The intermediate function that is called without changing the accepted independent variable. the list of returned results (the type of the list element is the result type returned by the corresponding command or event to I). The list is composed of the returned results returned by calling the intermediate function through a connection. An intermediate function that returns NULL values is suitable for commands or events that are not connected. An intermediate function that returns two or more values is suitable for "fan out ". NESC allows compilation without a direct intermediate function. Therefore, the behavior described in this section has no running overhead. The actual function call requires parameterized commands or events. Intermediate functions and structuresThe wiring description of a structure specifies the intermediate function body. First, we extend the wiring description to the intermediate function, not limited to the specification element, and cancel the difference between = and-> in the wiring description. We use I1 <-> I2 to represent the link between the intermediate functions I1 and I2. For example, structure C in Figure 1 describes the following intermediate function connections: 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. in Connection I1 <-> I2 of structure C, one of the two intermediate functions is called, and the other is called. I1 (likewise, I2) is called if any of the following conditions are true (we use an internal or external term for specification description that does not impede structure C inclusion connections: if I1 meets the internal specification element of a provided instruction or event. if I1 meets the external specification element of a used instruction or event. if I1 complies with the instructions of an interface instance X, and X is an internal and provided or external and used specification element. if I1 conforms to an interface instance x event, and X is an external and provided or internal and used specification element. if none of these conditions are true, the i1 caller. The wiring rules in section 7.2 ensure that one connection I1 <-> I2 does not connect two callers or two callers at the same time. In structure C of Figure 1, IC. x. f, IC. h2, im. p. g, im. u. f is the caller and IC. x. g, im. p. f, im. u. g, im. H is the caller. The C connection indicates that IC. X. F calls im. P. F, Im. p. g calls IC. X. G, and so on. Intermediate functions and modulesThe C code in the module calls the intermediate function or is called by the intermediate function. The intermediate function I in module M that provides commands or event a contains a separate call to run a in module M. The result is a separate call return list. The call a (E1,..., en) expression has the following properties: the independent variable E1,..., and EN is assigned to V1,..., vn .. The intermediate function corresponding to a is used as the independent variable V1 ,..., vn call, return result list L. if l = (w) (an independent list), the returned result of the call is W. if l = (W1, W2 ,..., WM) (two or more elements), the call result depends on the return type T of. If t = void, the result is void. Otherwise, T must have a federated Function C (section 10.3 demonstrates how a federated function is associated with a type); otherwise, a compilation-time error occurs. The Union function accepts two values of type T and returns the result of type T. The result of this call is C (W1, C (W2 ,..., C (WM & s722; 1, WM) (note that the element order in L is arbitrary ). 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 () ;}}figure 2: If the intermediate function in Figure 1 is null, the default value is V1 ,..., run a as the independent variable and return the call result. Section 7.4.2 indicates that if l is null and A has no default implementation, a compilation-time error will occur. The signal expression rules are the same. Intermediate function exampleFigure 2 uses the C-like syntax to demonstrate the intermediate functions generated by components in Figure 1. List (x) generates an independent list containing X, an empty list is a constant in the list containing 0 elements. The join List concatenates two lists in a chain. To call M. P. F, M. U. G, M. H, call the commands and events implemented in M of the module (not given ). 7.4.1 wiring and parameterization functions if a command or event a of component K carries a Type T1 ,..., the interface parameter of TN, then for each array (V1: T1 ,..., vn: tn) there is an intermediate function IA, V1 ,..., vn. In the module, if the intermediate function iv1 ,..., if VN complies with parameterized instructions (or events) A, then iv1 ,..., the call to the implementation of a in VN will pass V1 ,..., vn serves as the interface parameter of. The following is the call _ [e01 ,..., e0m] (E1 ,..., en) Discussion: independent variable E1 ,..., en is assigned V1 ,..., vn. The Independent Variables e01,..., and e0m are assigned v01,..., and v0m. V0i corresponds to the Ti type. Here, t I is the type of the I-th interface parameter of. The intermediate function iv01,..., and v0m corresponding to a are called with parameters V1,..., vn, And the list l is returned. If l has one or more elements and the call result is generated in non-parameterized conditions. If l is null, the default Implementation of A is as the independent variable V1 ,..., vn, with the interface parameter value v01 ,..., v0m call and return the call result. Section 7.4.2 indicates that if l is null and A is not implemented by default, a compilation-time error will occur. The rules of the signal expression are the same. When an endpoint in the wiring description is related to a parameterized specification element, there are two scenarios: the endpoint specifies a parameter value V1,..., vn. If the endpoint complies with the command or event A1 ,..., am, then the intermediate function is ia1, V1 ,..., vn ,..., iam, V1 ,..., vn and the wiring method remains unchanged. The parameter value is not specified for the endpoint. In this case, the two endpoints in the wiring description correspond to the parameter type elements of the same interface parameter Type T1,..., TN. If an endpoint corresponds to a command or event A1 ,..., AM and the other end point corresponds to the instruction or event β1 ,..., β m, then all 1 <= I <= m and all arrays (W1: T1 ,..., wn: tn) connected to IAI, W1 ,..., wn <-> I β I, W1 ,..., wn (that is ., the endpoint is connected to all corresponding values ).. 7.4.2 application-level requirements the wiring description of an application must meet two requirements. Otherwise, a compilation time error occurs: No infinite loop containing only intermediate functions. in each call A (or signal a) expression in the application module:-If the call is not parameterized: if the call returns an empty result list, then a must have a default implementation (the number of elements in the result list only depends on the wiring ). -If the call is parameterized: if any substitution value of interface parameter a returns an empty result list, then a must have a default implementation (the number of elements in the returned result list of the given parameter value array only depends on the wiring ). Note that this case is not used to describe the expression of interface parameter values at the call point. A special feature of this call is the selection of runtime options between several command executions-this is the only runtime overhead of the intermediate function. 8. NESC collaborationNESC uses a running model consisting of a running task (representative real-time computing) and a hardware asynchronous triggering interrupt control. The compiler uses the event handle and primitive features provided by the user to identify the interrupt source (see section 10.3 ). The NESC scheduler can run jobs in any order, but must comply with the rules once running until completion (Standard tinyos scheduler follows the FIFO (first-in-first-out) Policy ). because jobs cannot be exclusive and run until they are completed, they are independent of each other and can be interrupted. Due to this parallel running model, special data competition in the state of program sharing leads to unstable NESC program status. For example, its global and module variables (NESC does not include dynamic storage configuration). To avoid competition, either access the shared status only within the job or access only within the atomic declaration. During compilation, the NESC compiler reports potential data competition. In form, the NESC program code is divided into two parts: Synchronous Code sync (SC): the asynchronous code async (AC) that is only accessible within the job ): at least one code that can interrupt the source. although data competition between jobs is eliminated, there is still potential competition between SC and AC, as well as between AC and AC. Generally, any shared state update that is accessible from the AC is a potential data competition. the basic constant for running NESC is: non-competitive constant: Any sharing status update either only synchronizes the code reachable or only occurs within the atomic statement. as long as all calls to function f are within the atomic statement, we think that calls to function f are within the atomic statement. This may introduce a competition that the compiler cannot discover, but it must span multiple atomic statements or jobs and use intermediate storage variables. NESC may report data competition that will not actually happen, for example, if all paths are protected by the guard on other variables. In this case, to avoid more messages, the program comments a variable V with the storage type annotation to ignore all data competition warnings about v. Note keywords should be used with caution. For any asynchronous code that does not declare asynchronous commands or events, NESC reports a compilation-time error. This ensures that insecure code is not called accidentally when it is interrupted. 9 NESC ApplicationA nesc application has three parts.: A series of C statements and definitions, a group of interface types, and a group of components. The nameenvironment of the nesc application is constructed as follows: The Global nameenvironment of the outermost layer contains three namedomains: a c variable and a C tag namefield used for the c Declaration and definition, and a component and interface type namefield for the component and interface type. Generally, C statements and definitions can introduce their own nested naming fields (used for function declaration and definition of internal function code segments) in the global naming environment ). Each interface type introduces a namefield to save the commands or events of the interface. This naming field is nested in the global naming environment, so the command and event definitions can affect the C type and label definitions in the global naming environment. Each component introduces two new naming domains. The specification naming field is nested in the global naming environment and contains a variable naming field used to store component specification elements. The implementation namefield is nested in the Specification namefield and contains a variable and a label namefield. For the structure, the name field of the action range variable contains the name of the component referenced by the component that contains the component (section 7.1). For the module, the Action Scope stores the job, and the c Declaration and definition in the module body. These declarations and other naming fields (such as function bodies, code segments, and so on) that may introduce their own nesting within the scope of their function ). because of the nested structure of the naming domain, the code in the module can access the c Declaration and definition in the global naming environment, but cannot access any declaration or definition in other components .. The C description and definition of a NESC application. The interface type and component are determined by an on-demand loader. The input of the NESC compiler is a separate component K. The NESC compiler first loads the c file (section 9.1) and then the component K (section 9.2 ). The loading of all the code of the program is part of the process of loading these two files. The NESC compiler assumes that all calls to functions, commands, and events are not based on natural attributes (section 10.3) in the loaded Code (for example ., there is no "invisible" call to unnatural functions ). During file preprocessing, NESC defines the NESC symbol to recognize the numbers xyz of the nesc language and compiler version. For NESC 1.1, XYZ must be at least 110. The process of loading c files, NESC components and interface types includes locating corresponding resource files. The file locating mechanism is not discussed in this reference manual. To learn more about how a general compiler works, read the "the NCC man page." 9.1 load C file X. If X has been loaded, no more work is required. Otherwise, locate and pre-process the file X. h. Changes in the C macro definition (by # define and # UNDEF) will affect all subsequent file preprocessing. C Declarations and definitions from the pre-processed file X. H will enter the C global naming environment. Therefore, all subsequent C file processing, interface types, and components will be affected. 5. For example, the current NESC compiler uses this information to remove inaccessible code. 6 The NESC symbol is not defined in earlier versions of NESC. 9.2 load component K if K has been loaded, there is no need to do anything. Otherwise, locate and pre-process the file X. nc. Changes to the C macro definition (by # define and # UNDEF) are ignored. Use the following syntax to analyze the pre-processing file: NESC-file: includes-listopt interfacegatedes-listopt modulegatedes-listopt configurationgatedes-list: includesincludes-list includesincludes: Includes Identifier-list; If X. NC does not define module K or structure K, and will report compilation-time error. Otherwise, all the C Files specified in the include list will be loaded (section 9.1 ). Then, all interface types used in the component description will be loaded (section 9.3 ). Next, process the component description (section 5th). If K is a structure, all components specified by K (section 7.1) are loaded (section 9.2 ). Finally, K implementation is processed (sections 6th and sections 7th ). 9.3 load interface type I if I has been loaded, no more needs to be done. Otherwise, locate and pre-process the file X. nc. Changes to the C macro definition (by # define and # UNDEF) are ignored. The pre-processing file is analyzed like the NESC-File above. If X. NC does not define interface I, a compilation-time error is reported. Otherwise, all the C Files specified in the include list will be loaded (section 9.1 ). Next, process the definition of I (section 4th ).. As an example of a component or interface containing a c file, the interface type bar may contain the c file bartypes used to define the type used in the bar. h: bar. NC: bartypes. h: Includes bartypes; typedef struct {interface bar {int X; command result_t bar (bartype arg1); Double Y ;}} bartype; for interface bar definitions, see Bar type, similarly, any interface bar component can be used or provided (the interface bar must be loaded before any of these components are described or implemented. Naturally, there is also bartypes. h) 10 diversity10.1 The Old Style of c Declaration for functions without independent variables the NESC function without independent variables uses () Declaration instead of (void ). The usage of the latter will report a compilation-time error .. The old c Declaration (using () and Function Definition (specifying the parameter list after the independent variable) are not allowed in interfaces and components (causing compilation-time errors ). Note that these changes are not used in the C file (so that the existing. h file can be used without changing). 10.2 // note that NESC allows C, interface types, And/comments in the component file. 10.3 The attribute NESC declares some attributes, variables, and types of the function using the attribute Syntax of GCC. These attributes can be placed on the declaration (after the declaration) or function definition. (After the parameter list. The attribute of X is the set of all attributes in the declaration and definition of all X. The attribute Syntax of NESC is INIT-declarator-list: alsoinit-declarator attributesinit-declarator-list, init-declarator attributes-Definition: alsodeclaration-includeclarator attributes-statementattributes: attributeattributes attributeattribute: attribute (Attribute-list) Attribute-list: Single-attributeattribute-list, single-attributesingle-attribute: identifieridenti Fier (argument-expression-list) GCC does not allow attributes following the parameter list in function definition. NESC supports five attributes: C: This attribute is used to declare or define D as C at the top layer of a module (it is ignored by all other declarations ). this indicates that D should appear in the global scope, rather than the component scope of the module. This can be used in C Code (for example, if it is a function, it can be called) d. Naturally: This attribute can be used in any function f (in the module or C code ).. This indicates that the call to F is invisible in the source code. Typically, functions are naturally interrupted by the source, and C main function calls. Section 9th describes how the NESC compiler uses natural attributes during compilation. Event handle: This property can be used in any function f (in the module or C code ). It indicates that F is an interrupt processing function and is automatically called by hardware. This means that F is both natural and asynchronous code (AC ). Atomic event handle: This property can be used in any function f (in a module or C code ). It indicates that F is an interrupt processing function, which is automatically called by hardware to prevent interrupted operations. This means that F is both natural and asynchronous code (AC ). In addition, the F runtime seems to be encapsulated into an atomic statement. Fnname: This attribute specifies the Union function for a type in the Type Definition declaration. The federated function specifies how to call one command or event together and "fan out" multiple results returned. For example: typedef uint8_t result_t _ attribute _ (combine (rcombine); result_t rcombine (result_t R1, result_t R2) {return R1 = fail? Fail: R2;} describes logical-similar behavior when the returned type of a federated command (or event) is T. For detailed semantics, see section 7.4. If the Union function C of type T does not have type t c (t, t), a compilation time error occurs. Example of using properties: In the file realmain. in TD: module realmain {...} implementation {int main (INT argc, char ** argv) _ attribute _ (C, spontaneous )) {} This example shows that the main function should actually appear in the C global namespace (c), so the connector can find it. It also indicates that the main function can be called (naturally) even if no function is called in the program ). 10.4 compile-the time constant function NESC has a new type of constant expression: constant function. A constant function defined in a language is used as a constant during compilation. NESC now has two constant functions: Unsigned int unique (char * identifier) Return Value: if the program contains N calls to unique with the same string, each call returns a 0 ~ An unsigned integer between n-1. For example, if there are 10 unique ("ABC"), then the result of each unique ("ABC") is 1 ~ 9. Therefore, 10 unique ("ABC") is actually numbered from 0 to 9. Unique is used to pass a unique integer to an instance of the parameterized interface, so that a component can uniquely identify different components connected to that interface as long as a parameterized interface is provided. Unsigned int uniquecount (char * identifier) Return Value: if the program contains N calls to unique with the same string, each call returns N (the number of unique entries in the program ). Uniquecount is used to measure the size of an array (or other data structures). These arrays are indexed using the number returned by unique. For example, a timer Service identifies its customers through a parameterized interface (each independent timer comes from this), and uniquecount can be used to allocate the correct number of timer data structures.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.