Title: Programming SOS
1Programming SOS
- Simon Han
- (simonhan_at_ee.ucla.edu)
- EE202A Lecture
- October 17, 2005
2Embedded Software Development
- Development cycle
- Coding
- Cross-compile
- Upload binary
- Testing
- Cross-compiler
- A compiler which runs on one platform and
produces code for another. - Javac compile java source into java bytecode
- Avr-gcc compile C source into avr instructions
- Tool-chain
- Compiler binutils (linker, assembler)
libraries.
3SOS Operating System
- Problem With Writing Software on Sensor Node
- Unstructured Input from the Environment.
- Peer-to-peer Interaction.
- Resource Limitation.
- Evolving Application Requirements
- Mission change
- Multi-user
- Environmental uncertainties
- The SOS Solution
- Making software extensible
- Framework for writing extensible applications
with loadable modules. - Network Protocols for distributing software
extension.
SOS
4Architecture Overview
- Static Kernel
- Hardware abstraction and common services
- Costly to modify after deployment
- Data structures to enable module loading
- Dynamic Modules
- Drivers, protocols, and applications
- Inexpensive to modify after deployment
- Position independent
5SOS Concepts
- Inter-Module Message Passing Communication
- Inter-Module Function Calls
- Dynamic Memory Management (heap)
- Support Module Insertion
6Inter-Module Communication
- Inter-Module Message Passing
- Asynchronous communication
- Messages dispatched by a two-level priority
scheduler - Suited for services with long latency
- Inter-Module Function Calls
- Synchronous communication
- Kernel stores pointers to functions registered
by modules - Blocking calls with low latency
- Type-safe runtime function binding
7SOS Modules
- Each module is uniquely identified by its ID or
pid. - Module has private state.
- Modules can be loaded post-deployment.
- Modules can call function (cover later).
- Each module is represented by a message handler
and has following prototype. - int8_t handler(void private_state, Message msg)
- Each module is a finite state machine that
changes state based on messages. - Message handling can only be interrupted by
hardware. - There is no preemption!
- Return value follows errno.
- SOS_OK for success. -EINVAL, -ENOMEM, etc for
failure.
8Module Header
- Describes modules properties.
- Module ID,
- Resource requirements (memory and timer)
- Functions used,
- Functions provided,
- Limitations
- One header per C file. (No more, no less!)
- You have to write it! )
9Blink Module Header
- static mod_header_t mod_header SOS_MODULE_HEADER
-
- .mod_id DFLT_APP_ID0,
- .state_size sizeof(app_state_t),
- .num_timers 1,
- .num_sub_func 0,
- .num_prov_func 0,
- .module_handler module,
Guaranteed Timer
Message Handler
10Blink Module
- static int8_t module ( void state, Message msg
) - app_state_t s ( app_state_t ) state
- switch ( msg-gttype )
- case MSG_INIT
- s-gtstate 0 ker_led(LED_YELLOW_OFF)
- ker_timer_init ( s-gtpid, BLINK_TID,
TIMER_REPEAT ) - ker_timer_start ( s-gtpid, BLINK_TID, 1024 )
- return SOS_OK
- case MSG_TIMER_TIMEOUT
- if ( s-gtstate 1 )
- s-gtstate 0 ker_led ( LED_YELLOW_OFF )
- else
- s-gtstate 1 ker_led ( LED_YELLOW_ON )
-
- return SOS_OK
- case MSG_FINAL
- ker_timer_stop ( s-gtpid, BLINK_TID )
11SOS Messaging
- Task scheduling
- Send message to self
- Schedule timer for later message delivery
- Inter-module asynchronous communication
- Send message to other module
- Multi-level queues (currently Two)
- High priority Message for timely response.
- Network capable
- Same message format for both local message queue
and radio send queue. - Receive queue is local message queue.
12SOS Messaging and Modules
- Module is active when it is handling the message
(2)(4). - Message handling runs to completion and can only
be interrupted by hardware interrupts - But the SOS kernel traps the interrupts so they
are NEVER exposed to the modules - Module can send message to another module (3) or
send message to the network (5). - Message can come from both network (1) and local
host (3).
13Network Capable Messages
- typedef struct
- sos_pid_t did // destination module
ID - sos_pid_t sid // source module ID
- uint16_t daddr // destination node
- uint16_t saddr // source node
- uint8_t type // message type
- uint8_t len // message length
- uint8_t data // payload
- uint8_t flag // options (not sent
over network) - Message
- Messages are best-effort by default.
- No senddone and Low priority
- Can be changed via flag in runtime
- Messages are filtered when received.
- CRC Check and Non-promiscuous mode
- Can turn off filter in runtime
14SOS Messaging API
- // send message over net
- int8_t post_net (
- sos_pid_t did,
- sos_pid_t sid,
- uint8_t type,
- uint8_t length,
- void data,
- uint8_t flag,
- uint16_t daddr )
- // send long message
- int8_t post_long (
- sos_pid_t did,
- sos_pid_t sid,
- uint8_t type,
- uint8_t length,
- void data,
- uint8_t flag )
-
// send message int8_t post(Message msg) //
short message struct typedef struct uint8_t
byte uint16_t word MsgParam // send
short message int8_t post_short ( sos_pid_t
did, sos_pid_t sid, uint8_t type,
uint8_t byte, uint16_t word, uint8_t flag
)
15Synchronous Communication
- Module can register function for low latency
blocking call via module header (1). - Modules which need such function can subscribe it
by getting function pointer pointer (i.e. func)
(2). - Subscription can be static or dynamic
- When service is needed, module dereferences the
function pointer pointer (3).
16Module Header
- static mod_header_t mod_header SOS_MODULE_HEADER
-
- .mod_id MOD_FN_C_PID,
- .state_size sizeof(fnclient_state_t),
- .num_timers 1,
- .num_sub_func 2,
- .num_prov_func 0,
- .module_handler module,
- .funct
- 0 error_16, "Svv0", MOD_FN_S_PID,
MOD_GET_NODE_ID_FID, - 1 error_8, "cCC2", RUNTIME_PID,
RUNTIME_FID, - ,
Provider ID
Function ID
Function Prototype
Error Handler
17Module Header
- static mod_header_t mod_header SOS_MODULE_HEADER
-
- .mod_id MOD_FN_C_PID,
- .state_size sizeof(fnclient_state_t),
- .num_timers 1,
- .num_sub_func 2,
- .num_prov_func 0,
- .module_handler module,
- .funct
- 0 error_16, "Svv0", MOD_FN_S_PID,
MOD_GET_NODE_ID_FID, - 1 error_8, "cCC2", RUNTIME_PID,
RUNTIME_FID, - ,
Static Subscription
18Module Header
- static mod_header_t mod_header SOS_MODULE_HEADER
-
- .mod_id MOD_FN_C_PID,
- .state_size sizeof(fnclient_state_t),
- .num_timers 1,
- .num_sub_func 2,
- .num_prov_func 0,
- .module_handler module,
- .funct
- 0 error_16, "Svv0", MOD_FN_S_PID,
MOD_GET_NODE_ID_FID, - 1 error_8, "cCC2", RUNTIME_PID,
RUNTIME_FID, - ,
Dynamic Subscription
19Provider Module Header
- static mod_header_t mod_header SOS_MODULE_HEADER
-
- .mod_id MOD_FN_S_PID,
- .state_size 0,
- .num_timers 0,
- .num_sub_func 0,
- .num_prov_func 1,
- .module_handler module,
- .funct
- 0 mod_set_led, // Real
implementation - "cCC2",
- MOD_FN_S_PID, // My own ID
- MOD_SET_LED_FID, // function ID
- ,
20Synchronous Communication API
- // subscribe function at runtime
- int8_t ker_fntable_subscribe (
- sos_pid_t sub_pid, // subscriber module ID
- sos_pid_t pub_pid, // provider module ID
- uint8_t fid, // function ID
- uint8_t table_index // prototype location
- )
- define SOS_CALL(fnptrptr, type, args...)
\ - ((type)(sos_read_header_ptr(fnptrptr, 0))) (
\ - (fnptrptr), \
- args )
21Example
- typedef int8_t (set_led_proto)( func_cb_ptr,
uint8_t, uint8_t ) - typedef struct
- func_cb_ptr get_id
- func_cb_ptr set_led
- ltapplication specific state gt
- fnclient_state_t
- .funct
- 0 error_16, "Svv0", MOD_FN_S_PID,
MOD_GET_NODE_ID_FID, - 1 error_8, "cCC2", MOD_FN_S_PID,
MOD_SET_LED_FID, - ,
- SOS_CALL (
- s-gtset_led, // pointer to providers table
entry - set_led_proto, // prototype to prevent compiler
warning - RED, // first parameter to set_led
- TOGGLE) // second parameter to set_led
22SOS_CALL()
RAM
Flash
Flash
Header
Header
foo
..
no_foo
..
Provider Module
Subscriber Module
23SOS_CALL()
RAM
Flash
Header
no_foo
..
Provider Module
Subscriber Module
24Memory Management
- Modules need memory to store state information
- Problems with static memory allocation
- Worst case memory allocation every variable is
global - Single packet in the radio stack can lead to
race conditions - Problems with general purpose memory allocation
- Non-deterministic execution delay
- Suffers from external fragmentation
- Use fixed-partition dynamic memory allocation
- Memory allocated in blocks of fixed sizes
- Constant allocation time
- Low overhead
- Memory management features
- Guard bytes for run-time memory over-flow checks
- Semi-auto ownership tracking of memory blocks
- Automatic free-up upon completion of usage
25SOS Memory API
- // allocate memory to id
- void ker_malloc ( uint16_t size, sos_pid_t id )
- // de-allocate memory
- void ker_free ( void ptr )
- // Get memory block size
- uint16_t ker_mem_block_size ( void ptr )
- // Take data from msg-gtdata
- uint8_t ker_msg_take_data(sos_pid_t id, Message
msg_in)
26Messaging and Dynamic Memory
- Messaging is asynchronous operation. Attaching
dynamic memory in post() results transfer of
ownership. - Bit Flag is used to tell SOS kernel the existence
of dynamic memory. - SOS_MSG_RELEASE -- sender decided to give up the
ownership - SOS_MSG_RELIABLE -- sender requests message
acknowledgement. - Dynamically allocated message payload will be
automatically freed after module handling. - This is the default. You can use
ker_msg_take_data(). - Message header belongs to the kernel, and it will
be recycled. If you need them, make a deep copy.
27Asynchronous Module Kernel Interaction
- Kernel provides system services and access to
hardware - Kernel jump table re-directs system calls from
modules to kernel handlers - Hardware interrupts and messages from the kernel
to modules are dispatched through a high priority
message buffer - Low latency
- Concurrency safe operation
28Schedule Message with Software Timer
Module A
Timer syscall
Timer Messages
High Priority Message Buffer
System Jump Table
SOS Kernel
Interrupt
Timer API
Delta Timer
- Two priority high and low.
- Normal timer has high priority while slow timer
is not. - Two types periodic and one shot
29SOS Timer API
- enum
- TIMER_REPEAT 0, // high priority,
periodic - TIMER_ONE_SHOT 1, // high priority, one
shot - SLOW_TIMER_REPEAT 2, // low priority,
periodic - SLOW_TIMER_ONE_SHOT 3, // low priority, one
shot -
- int8_t ker_timer_init (
- sos_pid_t pid, // module id
- uint8_t tid, // timer id
- uint8_t type // timer type
- )
- int8_t ker_timer_start(
- sos_pid_t pid, // module id
- uint8_t tid, // timer id
- int32_t interval // binary interval
- )
- int8_t ker_timer_stop(
- sos_pid_t pid, // module id
- uint8_t tid // timer id
Slide is Wrong!
30Timer Example Blink
- static int8_t module ( void state, Message msg
) - app_state_t s ( app_state_t ) state
- switch ( msg-gttype )
- case MSG_INIT
- s-gtstate 0 ker_led(LED_YELLOW_OFF)
- ker_timer_init ( s-gtpid, BLINK_TID,
TIMER_REPEAT ) - ker_timer_start ( s-gtpid, BLINK_TID, 1024 )
- return SOS_OK
- case MSG_TIMER_TIMEOUT
- MsgParam params ( MsgParam )( msg-gtdata )
- if ( params-gtbyte BLINK_TID )
- if ( s-gtstate 1 )
- s-gtstate 0 ker_led ( LED_YELLOW_OFF )
- else
- s-gtstate 1 ker_led ( LED_YELLOW_ON )
-
-
- return SOS_OK
31Static Verification of SOS Modules
- A framework for statically analyzing SOS module
code is under development - At compile time the source code for a module can
be examined to verify various properties - Checker is automatically run on ee202a accounts
on grian.nesl.ucla.edu by executing the 'check'
target before making the module - Output is similar to that for the compiler and
can be desabled by setting QUIET to 1 at build
time using 'make mica2 QUIET1'
32Checked Properties
- Style checks
- All modules should have an INIT and FINAL message
handler - Some return values should be checked by the
programmer - No global should be used in a module
- Memory ownership tracking
- All dynamically created memory should be
controlled by a single module - The controlling module is responsible for freeing
the data, releasing ownership to another
module, or storing a persistent reference to the
data - Freed or released data must not escape through
persistent references and should be treated as
dead after the free or release
33Network Simulation Support
- Source code Level Network Simulation
- Each process runs one SOS.
- Pthread is used to simulate hardware.
- UDP is used to simulate communication with simple
radio channel. - Support user defined topology and heterogeneous
software configuration. - Behavior simulation.
- Avrora Instruction Level Simulation
- Instruction cycle accurate simulation.
- Simple perfect radio channel.
- Useful for verifying timing information.
- See http//compilers.cs.ucla.edu/avrora/
34SOS_SERVER
SOS emu
SOS mica2
TCP
SOS mica2
UART
SOS mica2
TCP
GUI
sos_server
- Bridge PC tools and sensor nodes.
- Broadcast messages from UART to all TCP ports
- Uni-cast messages from TCP port to UART
- Unfortunately, this is the only way to run our
module insertion tool.
35Simulation Options
SOS emu
SOS avrora
TCP
SOS avrora
TCP
SOS avrora
TCP
GUI
sos_server
SOS emu
SOS sim
TCP
SOS sim
TCP
SOS sim
TCP
GUI
sos_server
36Application Development Cycle
Code Development
Linker determines Memory mapping (see arm.ld)
Compile Link
File output format Can be elf, bin, hex
Upload Code to Chip
.elf for JTAG Or .hex for serial port
Run/Debug
37Software Engineering Practices
- Make use of CVS for development coordination
(also backup and revision control) - If you write something, make it modular(drivers,
task, library) - Spend extra time to refine the interface so that
other people can easily use it - Write a simple example code that can test your
contributed module - More you contribute, more useful it becomes ?
Everybody counts!
38SOS Directory Layout
- sos/config Application directory
- blank Application with just SOS core
- blink Blink application
- sender Periodic packet sending
- sos/platform Device specific directory
- mica2 mica2 hardware device drivers
- micaz micaz hardware device drivers
- emu Gateway(PC) hardware device drivers
- sim Simulated hardware device drivers
- xyz XYZ device driver
- Sos/processor
- oki OKI ARM7TDMI
- avr Atmel 128L
- posix device drivers build on top of
posix - sos/doc SOS Documentation directory
39CVS Access
- export CVSROOT anon_at_cvs.nesl.ucla.edu
- /Volumes/Vol1/neslcvs/CVS
- export CVS_RSHssh
- cvs co sos-1.x
- password anon
- echo happy hacking
40References
- SOS Website
- http//nesl.ee.ucla.edu/projects/sos-1.x
- Papers
- Simon Han, Ramkumar Rengaswamy, Roy S Shea, Eddie
Kohler, Mani B Srivastava, "A Dynamic Operating
System for Sensor Nodes," Mobisys - June 2005 - http//nesl.ee.ucla.edu/projects/sos/publications/
sosmobisys05.pdf