System development Language Nesc
TinyOS was originally written in Assembler and C, and in implementing the TinyOS time-and component-based execution model, a large number of macro definitions were needed to reduce the amount of code that was programmed. The large use of macro definitions makes the development of tinyos components cumbersome.
Therefore, the developer designed the Nesc language as the embedded operating system of the wireless sensor network programming language, it is completely appropriate to the wireless sensor network operating system requirements of the programming language, it overcomes the C language of many shortcomings to improve code efficiency and code robustness. The Nesc language has syntax similar to the C language, but supports the TinyOS concurrency model and has a component-based mechanism that can be connected with other components to form a robust embedded system.
Nesc defines a number of important concepts that are expressed in TinyOS:
(1) The NESC application is built on a well-defined, bidirectional interface-based component that embodies the full component characteristics of the TinyOS.
(2) Nesc defines the concurrency model, which is based on tasks (task) and hardware event handles (hardware event handler), which enables the TinyOS event-driven mechanism to be better implemented.
The Nesc component model.
The component model of Figure NESC
1. Interface (interface)
In the Nesc bidirectional component model, both the provider and the caller of the component's function must prescribe a uniform invocation specification (function), and the set of these specifications can be represented by an interface, so the interface can also be called a collection of function prototypes.
Function prototypes in interfaces differ from those of the general C language, and are divided into commandsand events (event) In both cases, the command is a function implemented by the component that provides the interface, and the event is implemented in the component that uses the interface. The high-level components issue commands to the underlying components, initiating the functionality of the underlying components, and reporting the events to the high-level components after the underlying components have completed their functions. For example:
Interface amsend{
commanderror_t Send (message_t* msg, uint8_t len);
Eventvoid Senddone (message_t* msg, error_t error);
}
In the interface amsend, a command send and an event senddone are defined. NESC command commands are prefixed with the keyword call, and when the event is notified, the keyword signal is used to complete the notification of the event. . If the upper-level routing component ROUTEENGINEP needs to invoke the Amsend interface provided by the underlying ACTIVEMESSAGEC to send the routing update information, then the statement call Amsend.send (MSG, Len) needs to be used in ROUTERENGINEP To send, when the underlying component through the radio frequency to send this information successfully, will use the statement Signalamsend.senddone (MSG, SUCCESS) to notify the completion of the event, so the Send.senddone event in Routeenginep is called.
2. Component (components)
Any NESC application is linked together by one or more components to form an executable program. Component provides ( provides ) and use ( uses ) interface. in the Nesc language, there are two types of components , called modules (module) and configurations (configuration ). The module implements the specific logic functions, including the provided and used interfaces, as well as the command to implement the interface and events (event) that use the interface, and the configuration is a special component for assembling a series of components, It connects the interfaces used by the internal components with the interfaces provided by the other components . Each NESC application is described by a top-level configuration whose content is to connect all the components of the application to form an organic whole.
3. Connection (wiring)
The configuration connects the interfaces of the internal components, which is the connection (wiring), which associates the provider of the interface with the consumer of the interface. The connection operation isdenoted by the "-a" sign, and its general meaning can be understood as "user to Provider", which is the arrow from the caller to the provider .
An example of a component and a connection is given below:
Module blink{//Modules components
Usesinterface timer<tmilli> as Timer0; Using an interface with parameters, Tmilli indicates the use of milliseconds
Usesinterface Leds; Timer
Usesinterface Boot;
}
Implementation {
Eventvoid Boot. Booted () {//main function start end, notify event booted
Calltimer0.startperiodic (1000); Invoke Command Start timer
}
Eventvoid timer0.fired () {//timer end, notification event fired
Callleds.led0toggle (); Call the Led0toggle in the LED interface to make the LED light flash.
}
}
Config blinkappc{//configuration component, because it is the topmost configuration, it does not use or provide an interface
}
implementation{
Componentsmainc, BLINKC, LEDSC; declaring components
Componentsnew timermillic () as Timer; Instantiating a generic (generic) component
Blinkc.boot-> Mainc.boot; Connection
Blinkc.timer0-> Timer.timer0;
Blinkc.leds-> LEDSC;
}
The function of the application is to turn on a timer for periodic timing, and the LED will blink once at a time. Wherein, BLINKC is the module component, it realizes the logic function counts, the LED light blinks function, the BLINKAPPC is the configuration, will BLINKC uses the interface Timer0, the Boot, the LEDs and the interface provider Timermillic, Mainc, LEDSC connect together.
In addition, the Nesc language provides a concurrency model for task support TinyOS.
System development Language Nesc