nesc announcement
play

nesC Announcement Programming language for TinyOS and applications - PDF document

nesC Announcement Programming language for TinyOS and applications Slides available online. Support TinyOS components and event/command Open floor discussions. Whole-program analysis at compile time Improve robustness:


  1. nesC Announcement • Programming language for TinyOS and applications • Slides available online. • Support TinyOS components and event/command • Open floor discussions. • Whole-program analysis at compile time • Improve robustness: Detect race conditions • Student presentations. • Optimization: function inlining • Static language • No function pointer • No malloc • Call graph and variable access are known at compile time Chenyang Lu 1 Chenyang Lu 2 Interface Application interface Clock { command error_t setRate(char interval, char scale); • Implementation • Interfaces event error_t fire(); • module: C behavior • provides interface } • configuration: select • uses interface interface Send { and wire command error_t send(message_t *msg, uint16_t length); event error_t sendDone(message_t *msg, error_t success); } module TimerP { StdControl Timer provides { interface ADC { interface StdControl; command error_t getData(); TimerP interface Timer; event error_t dataReady(uint16_t data); } } Clock uses interface Clock; ... Bidirectional interface supports split-phase operation } Chenyang Lu 3 Chenyang Lu 4 module SurgeP { provides interface StdControl; Module Configuration uses interface ADC; uses interface Timer; uses interface Send; } StdControl Timer implementation { configuration TimerC { bool busy; provides { norace uint16_t sensorReading; interface StdControl; async event result_t Timer.fired() { StdControl Timer interface Timer; bool localBusy; atomic { } TimerP localBusy = busy; } Clock busy = TRUE; implementation { } components TimerP, HWClock; if (!localBusy) call ADC.getData(); StdControl = TimerP.StdControl; return SUCCESS; Clock Timer = TimerP.Timer; } async event result_t ADC.dataReady(uint16_t data) { HWClock sensorReading = data; TimerP.Clock -> HWClock.Clock; post sendData(); } TimerC return SUCCESS; } ... } Chenyang Lu 5 Chenyang Lu 6

  2. Example: Surge Concurrency • Race condition: concurrent interrupts/tasks update SurgeC shared variables. StdControl SurgeP BootC StdControl ADC Timer SendMsg Leds • Asynchronous code (AC): reachable from at least one interrupt handler. • Synchronous code (SC): reachable from tasks only. StdControl ADC StdControl Timer StdControl SendMsg Leds PhotoC TimerC MultihopC LedsC • Any update of a shared variable from AC is a potential race condition Chenyang Lu 7 Chenyang Lu 8 module SurgeP { ... } A Race Condition implementation { bool busy; Atomic Sections norace uint16_t sensorReading; async event result_t Timer.fired() { atomic { if (!busy) { busy = TRUE; <Statement list> call ADC.getData(); } } return SUCCESS; } task void sendData() { // send sensorReading adcPacket.data = sensorReading; • Disable interrupt when atomic code is being executed call Send.send(&adcPacket, sizeof adcPacket.data); return SUCCESS; • But cannot disable interrupt for long! } async event result_t ADC.dataReady(uint16_t data) { • No loop sensorReading = data; • No command/event post sendData(); return SUCCESS; • Function calls OK, but callee must meet restrictions too } Chenyang Lu 9 Chenyang Lu 10 module SurgeP { ... } Prevent Race implementation { bool busy; nesC Compiler norace uint16_t sensorReading; async event result_t Timer.fired() { disable • Race-free invariant : Any update to a shared variable is bool localBusy; interrupt atomic { either test-and-set localBusy = busy; • from SC only, or busy = TRUE; enable } • occurs within an atomic section. interrupt if (!localBusy) • Compiler returns error if the invariant is violated. call ADC.getData(); return SUCCESS; • Fix } task void sendData() { // send sensorReading • Make access to shared variables atomic. adcPacket.data = sensorReading; • Move access to shared variables to tasks. call Send.send(&adcPacket, sizeof adcPacket.data); return SUCCESS; } async event result_t ADC.dataReady(uint16_t data) { sensorReading = data; post sendData(); return SUCCESS; Chenyang Lu 11 Chenyang Lu 12 }

  3. Results Optimization: Inlining • Tested on full TinyOS code, plus applications App Code size Code Data CPU • 186 modules (121 modules, 65 configurations) size reduction reduction inlined noninlined • 20-69 modules/app, 35 average Surge 14794 16984 12% 1188 15% • 17 tasks, 75 events on average (per application) Maté 25040 27458 9% 1710 34% • Lots of concurrency! TinyDB 64910 71724 10% 2894 30% • Found 156 races: 103 real! • About 6 per 1000 lines of code • Inlining improves performance and reduces code size. • Fixing races: • Why? • Add atomic sections • Post tasks (move code to task context) Chenyang Lu 13 Chenyang Lu 14 Overhead for Function Calls Principles Revisited • Caller: call a function • Support TinyOS components: interface, modules, • Push return address to stack configuration • Push parameters to stack • Whole-program analysis and optimization • Jump to function • Callee: receive a call • Enhance robustness: no race. • Pop parameters from stack • Optimization: inlining. • Callee: return • More: memory footprint. • Pop return address from stack • Static language • Push return value to stack • No malloc, no function pointers • Jump back to caller • Caller: return • Pop return value Chenyang Lu 15 Chenyang Lu 16 Reading • D. Gay, P. Levis, R. von Behren, M. Welsh, E. Brewer, and D. Culler, The nesC Language: A Holistic Approach to Networked Embedded Systems. Chenyang Lu 17

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend