1 / 54

Real-Time Software Components A Scalable Component Model for Embedded C Development

Real-Time Software Components A Scalable Component Model for Embedded C Development. Dave Russo, Texas Instruments Eclipse DSDP/RTSC Project Lead. 1. . QUALITY. In 25 Words Or Less. RTSC is a suite of foundational tools for building, testing, and deploying

hedy
Download Presentation

Real-Time Software Components A Scalable Component Model for Embedded C Development

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Real-Time Software ComponentsA Scalable Component Model for Embedded C Development Dave Russo, Texas Instruments Eclipse DSDP/RTSC Project Lead 1

  2. QUALITY In 25 Words Or Less .... RTSC is a suite of foundational tools for building, testing, and deploying re-usable target software content for diverse embedded platforms C-based software component model without compromising system performance !

  3. Key Characteristics Benefits Application Application B A C A RTSC Component A RTSC Component C RTSC Component B target-code target-code target-code (C) target-code (C) target-code (C) target-code (C) target-code (C) meta-code (JavaScript) meta-code (JavaScript) meta-code (JavaScript) RTSC Components • dual-existence • target-code: runs on resource limited HW • meta-code: runs on rich client platforms • meta-code manages component lifecycle • build of component (including target-side) • integration during application assembly • monitoring during test andafter deployment • significant design-time optimizations • transparently bind alternate implementations • objects can be created at design-time • minimal embedded runtime requirements • enables new tooling opportunities • meta-code can proxy for target-code • components differentiate in meta-domain Rich Client Platform Embedded Platform

  4. Outline • Demo of a “real” wireless sensor application • no more toy examples: a realistic complete RTSC-based application on an MSP430 • Embedded “Hello World” • everything it takes to get “hello world” operating on any HW platform using Eclipse CDT • Real-time analysis/visualization of deeply embedded applications • leveraging xdc.runtime’s built-in support for runtime visibility • Architectural and implementation highlights of the demo application • overview of demo application highlighting techniques and concepts discussed in this tutorial

  5. MSP430F2274 push button leds CR2500 Timer A 1KB RAM 0x200 : 0x600 Timer B WDT Antenna UART 32KB Flash 0x8000 : 0xFFFF GPIO ADC-10 eZ430-RF2500 Hardware • MSP430F2274: 16-bit microcontroller, 1KB data RAM, 32KB ROM (Flash) • one push button, two leds (red and green) • CCR2500: 2.4-GHz radio-frequency (RF) transceiver

  6. End Device End Device MSP430 MSP430 AAA AAA Access Point MSP430 UART Wireless Sensor Application • Multiple low-power temperature sensors • End Device transmits 1/sec to an Access Point • One Access Point always powered • Access Point communicates via UART to Host • Host interprets & displays sensor data • Host also controls Access Point via UART Eclipse Platform (Windows) eZ430-RF2500 Platforms

  7. Demo Wireless Application

  8. End Device(s) End Device End Device mon_ED.c MSP430 MSP430 AAA AAA xdc.runtime local.rf Log Radio Bsp local.runtime LogCallback Access Point mon_AP.c Host Control Application xdc.runtime local.rf System Log Radio Bsp xdc.rta local.console Access Point Main Decoder MSP430 local.runtime HostEvent SysUart LogUart xdc.tools.sg UART Wireless Sensor Architecture • Apps fully leverage RTSC modules • xdc.runtime reuse, leverage tooling support • Reuses existing SimpliciTI Radio stack • “no changes” needed to integrate this code • Embeds RTSC Real-Time Analysis • explicit “printf” & implicit runtime visibility • Host application is RTSC meta-module • xdc.rta decodes: minimizing target overhead SimpliciTI SimpliciTI Eclipse Platform (Windows) eZ430-RF2500 Platforms

  9. System Timestamp Log Gate ISystemSupport ITimestampProvider ILogger IGateProvider local.runtime SysMin TimestampNull LoggerBuf GateNull HeapMin SysUart LogUart GateGIE HeapNull The xdc.runtime Package • basic OS-independent services • used by virtually any embedded code • enables portable “middle-ware” • clients are platform independent • provided in source, BSD licensed • 100% portable: builds using any C toolchain • extended without modifying the source • transparently bind alternate implementations middle-ware Assert Startup Error Diags Memory IHeap Text platform-specific adaptors startup/shutdown diagnostics memory mgmt concurency Embedded Platform

  10. End Device MSP430 AAA ED ROM space Access Point MSP430 AP ROM space Wireless Sensor Performance • 18 modules used by both AP& ED • un-optimized, yet room for more • printf BSS exceeds total AP RAM #include <stdio.h> int main() { printf("Hello World\n"); }

  11. http://rtsc.eclipse.org • RTSC-Pedia: all RTSC documentation: primers, FAQs, examples … • RTSC White Paper: high-level introduction to RTSC • XDCtools User’s Guide: using XDCtools to create & use components • XDCtools: the starting point for the RTSC project’s code base Summary • RTSC components scale to highly-resource contained platforms 18 modules, runtime controllable trace in < 115 bytes RAM and 3K bytes ROM • RTSC content integrates well with existing software re-used existing SimpliciTI stack with “no modifications” • Dual-domain enables real-time visibility into deployed end-devices by decoding events on host, device overhead is minimal but visibility is high

  12. txn.targets txn.targets.rts430 txn.platforms.ez430_rf2500 local.runtime MSP430 boot.c Platform Platform linkcmd.xdt SysUart … … … created early in development, rarely changed, highly reused content development Embedded “Hello World” target-specific • need to chose a cross-compiler and runtime model for the device • create a package containing a module that inherits xdc.bld.ITarget: txn.targets • need compiler-specific “build” of the xdc.runtime modules • create a package to build and house the libraries: txn.targets.rts430 platform-specific • need linker description of memory map, interrupt vectors, etc. • create package containing an IPlatform module: txn.platforms.ez430_rf2500 • need platform-specific extensions of xdc.runtime modules • create a package with implementations of xdc.runtime interfaces: local.runtime

  13. xdc .c, .asm build processing .c, .asm, … config.bld package.bld txn.targets xdc.bld MSP430 ITarget package.mak libraries, … make –f xdc/bld/xdc.mak … RTSC Targets • RTSC targets encapsulate cross-compilers and their runtime models • targets are modules that inherit the xdc.bld.ITargetmeta domain interface • ITarget is used by xdc to generate the package.mak makefile • package.mak directs GNU make 3.81 to build package contents • targets enable RTSC to be extended to work with any C toolchain • leveraging RTSC meta-modules, anyone that can create a module can add a new target

  14. MSP430 MSP430X #include <xdc/std.h> int main() { : txn.targets xdc ti.targets xdc.bld std.h IMSP430 ITarget ITarget The MSP430 Target • target are modules, in any package, that inheritxdc.bld.ITarget must implement the methods and supply the configuration parameters declared in xdc.bld.ITarget inheritance in the meta-domain includes implementation of base methods • targets can leverage existing xdc.bld.ITarget implementations IMSP430 encapsulates common MSP430 definitions and inherits ti.targets.ITarget XDCtools includes GCC and Microsoft targets from which other targets can inherit • targets must define RTSC “portable” types; UArg, Int8, Int16, Int32, ... clients always include <xdc/std.h> which #includes target-specific definitions target-specific definitions specified by “-Dxdc_target_types__=txn/targets/std.h”, for example std.h

  15. config.bld txn.targets txn.targets.rts430 xdc.runtime MSP430 boot.c package.bld : package.mak MSP430X Log.c : System.c libraries Target-specific xdc.runtime • xdc.runtime delivered as re-buildable portable sources • xdc.runtime provides headers and sources only; no libraries • libraries built in separate package: xdc.runtime never modified by user • cleanly separates user-specific additions (e.g., boot files) and targets from xdc.runtime updates • txn.targets.rts430 is largely target independent • this package builds and supplies libraries for any target that names it as it’s rts package build.xs

  16. Review and build txn.targets.rts430

  17. platform name target name prog.cfg configuration processing xdc.cfg txn.platforms… Main prog_x430.xdl linkcmd.xdt LINKER prog_x430.c xdc.platform prog.out Platform IPlatform COMPILER prog_x430.o RTSC Platforms • RTSC platforms encapsulate a HW-platform's memory map, loader, … • platforms are instances of a module named Platform that implements xdc.platform.IPlatform • IPlatform is used by xdc.cfg to generate a linker command file • prog_x430.xdl defines memory map (if necessary) and lists all libraries with which to link • platforms enable RTSC to be extended to work with any HW platform • IPlatform is vendor neutral and anyone that can create a RTSC module can also add a new platform

  18. load.* linkcmd.xdt prog_x430.xdl : txn.catalog.c430 … MSP430F227x MSP430F223x ICPUDataSheet IMSP430x22xx The ez430_rf2500 Platform • linkcmd.xdt is the template that generates the linker command file • we could support multiple toolchains but for simplicity we assume the TI compiler • memory map is defined by modules in the txn.catalog.c430 package • allows multiple HW platforms to share common device memory map, simplifying Platform packages • load.* files support loading & running executables using TI-debugger • this platform could easily support other toolchains (e.g., a gdb-based solution) xdc.platform txn.platforms.ez430_rf2500 IPlatform Platform

  19. Platform-specific xdc.runtime System Timestamp Log Gate Memory ISystemSupport ITimestampProvider ILogger IGateProvider IHeap • local.runtime contains MSP430-specific extensions of xdc.runtime some modules are highly portable, others are platform and even application-specific • “Hello World” only requires one module: local.runtime.SysUart • others are added only as needed since reasonable defaults already exist in xdc.runtime #include <xdc/runtime/System.h> void main() { System_printf("Hello World\n"); } xdc.runtime Assert Startup Error Diags Text local.runtime SysUart LogUart GateGIE HeapNull ez430-rf2500 HW Platform

  20. The SysUartModule public SPECIFICATION ANSI C target-language internal IMPLEMENTATION @ModuleStartup module SysUart inherits ISystemSupport { typedef Void (*GetLineFxn)(Char *, Int); config GetLineFxn getLineFxn = null; } SysUart.xdc #include <xdc/runtime/Startup.h> #include <ti/apps/msp430/msp430x22x4.h> #include "package/internal/SysUart.xdc.h" Int SysUart_Module_startup(Int state) { WDTCTL = WDTPW + WDTHOLD; : /* initialize UART HW here */ return (Startup_DONE); } Int SysUart_putch(Char ch) { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = ch; } SysUart.c SysUart.xs function module$use() { xdc.useModule("xdc.runtime.Startup"); } XDCscript meta-language

  21. "Hello World\n"Program config.bld var MSP430 = xdc.module("txn.targets.MSP430"); MSP430.rootDir = …; MSP430.platform = "txn.platforms.ez430_rf2500"; Build.targets[MSP430]; hello.cfg var System = xdc.useModule("xdc.runtime.System"); configuration generated files package.bld xdc.runtime var targ = Build.targets[0]; var exe = Pkg.addExecutable( "hello", targ, targ.platform); exe.addObjects(["hello.c"]); SysUart SupportProxy System int putch() int putch() int printf() : local.runtime hello_x430.c Log txn.targets.rts430 hello_x430.xdl hello.c var System = xdc.useModule("xdc.runtime.System"); var SysUart = xdc.useModule("local.runtime.SysUart"); System.SupportProxy = SysUart; #include <xdc/runtime/System.h> int main() { System_printf("Hello World\n"); return 0; }

  22. Review, build, and run local.apps.hello_0

  23. "Hello World\n"Performance #include <xdc/runtime/System.h> int main() { System_printf("Hello World\n"); return 0; } xdc.runtime System SysUart int putch() int printf() UART ASCII characters local.runtime Terminal Embedded Platform • much better than full ANSI printf() • TI printf() for MSP430 requires 11KB • simple and robust • perfect for initial platform bootstrap • argument formatting on target • slow, non-deterministic, incomplete • clarity verses performance tradeoff • clear messages use more bandwidth,… all values in bytes

  24. Leveraging the Host /* create a decoder for the app */ var dec = Packages.xdc.rta.Decoder("app.out"); /* open stream of of events */ var in = java.io.FileReader("output.dat"); /* read next event from the file into buf */ while (readEvent(in, buf) != -1) { /* decode the event and print it */ var e = dec.apply(buf); print(e.eventMsg); } #include <xdc/runtime/Log.h> int main() { Log_print0(…, "Hello World\n"); return 0; } local.console Main xdc.rta Decoder HostEvent apply(byte[]) local.runtime xdc.runtime … LogUart Log HostEvent void write4() int print0() timstamp sequence event id arg 0 : Rich Client Platform Embedded Platform • even smaller than System printf • deterministic overhead • full ANSI printf formatting • runtime controllable • rich host-side display & analysis

  25. Module-Specific Data Analysis Domain-Specific Displays Real-Time Trace Logging Leveraging the Host CPU Load

  26. “printf” Performance Summary #include <stdio.h> int main() { printf("Hello World\n"); } printf • full ANSI fmt compatibility • big, slow, non-deterministic #include <xdc/runtime/System.h> int main() { System_printf("Hello World\n"); } System_printf • smaller, simple & reliable • non-deterministic, subset #include <xdc/runtime/Log.h> #include <xdc/runtime/Diags.h> int main() { Log_print0(Diags_ENTER, "Hello World"); } Log_printf • small and deterministic • full ANSI fmt compatibility* • runtime controllable * coming soon

  27. xdc.runtime.Main common$ : logger mask app.c ModA.c LogUart.c ModZ.c : Log_write1(evt, 3); : LogUart_write4(…) { : } : Log_write1(evt, 6); : : Log_write1(evt, 28); : common$ common$ common$ : logger = NULL : : logger mask : logger mask LogUart:inst#0 Log Runtime Architecture • all RTSC modules have a common configuration parameter: common$ • Mod.common$ is a structure valued meta config parameter defined by xdc.runtime.Types.Common$ • all modules have an xdc.runtime.ILogger logger and a 16-bit mask • all events produced by a module are handled by the module’s logger, the mask enables/disables events • all non-module code is represented by xdc.runtime.Main • all code in an application can be viewed has having xdc.runtime.Types.Common$ config parameters Application LogUart xdc.runtime.ILogger ModA ModZ …

  28. Log APIs prog.c prog.cfg output this is printed module = xdc.runtime.Main event = xdc.runtime.Log_print timestamp = … sequence = … • Log methods have an implied module-specific logger argument • the logger used is the logger associated with the “current module”, this logger is created via config • each module's “diagnostic mask” can be controlled at runtime • events have multiple levels, can be controlled at config time or runtime, and start enabled or disabled • Log events triggered only if the module’s mask & event mask intersect #include <xdc/runtime/Log.h> #include <xdc/runtime/Diags.h> #include <xdc/runtime/Main.h> int main() { Log_print0(Diags_ENTRY, “not printed"); /* enable ENTRY trace */ Main_Module_setMask(Diags_ENTRY); Log_print0(Diags_ENTRY, "this is printed"); Log_print0(Diags_EXIT, "this isn't"); return 0; } var Log = xdc.useModule("xdc.runtime.Log"); var Diags = xdc.useModule(“xdc.runtime.Diags"); var Main = xdc.useModule(“xdc.runtime.Main"); var Logger = xdc.useModule("…"); Main.common$.logger = Logger.create(); Main.common$.diags_ENTRY = Diags.RUNTIME_OFF; Main.common$.diags_EXIT = Diags.RUNTIME_OFF;

  29. ImplicitLogging prog.c prog.cfg var Diags = xdc.useModule("xdc.runtime.Diags"); var ModA = xdc.useModule("pkg.ModA"); var Logger = xdc.useModule("…"); ModA.common$.logger = Logger.create(); ModA.common$.diags_ENTRY = Diags.RUNTIME_ON; #include <pkg/ModA.h> void main() { ModA_start(1, 2); /* disable all ModA trace */ ModA_Module_setMask(0); ModA_write("test"); } output -->start(1, 2) event = pkg.ModA_start$ENTER timestamp = … : <--start: 0 event = pkg.ModA_start$EXIT : ModA.xdc moduleModA { Boolstart(Inta,Intb); Intwrite(Stringtext); } • All module method calls and returns can be logged • module entry and exit logging is controllable at conf or runtime • entry events log parameters passed, exit trace logs return value

  30. http://rtsc.eclipse.org • RTSC-Pedia: all RTSC documentation: primers, FAQs, examples … • RTSC White Paper: high-level introduction to RTSC • XDCtools User’s Guide: using XDCtools to create & use components • XDCtools: the starting point for the RTSC project’s code base Summary • RTSC can be used with any hardware supported by a C compiler targets abstract the compiler and platforms abstract hardware • Dual-domain enables real-time visibility into deployed end-devices by decoding events on host, device overhead is minimal but visibility is high • xdc.runtime provides services required by “all” embedded code from system startup, basic printf, and mutexes to real-time system monitoring

  31. txn.targets local.runtime local.apps.monitor mon_ED.c mon_AP.c MSP430 SysUart … … txn.targets.rts430 local.runtime.utils local.apps.hello_0 hello.c hello.cfg boot.c Stack … txn.platforms.ez430_rf2500 local.rf local.apps.hello_1 hello.c hello.cfg Platform Platform linkcmd.xdt Radio Bsp BuildOpts txn.catalog.c430 local.console IMSP430… MSP430F227x Main : Tutorial Package Overview Targets and Platforms Support Libraries & Utilities Applications reused by all applications for this hardware platform reused by a family of related applications

  32. Supplementary Topics

  33. Outline • Tutorial software installation • how to get and install the software necessary to build/run/debug the demo application • Basic RTSC-CDT integration • basic Eclipse integration used to develop the demo apps shown in the tutorial • xdc.runtime Log architecture • how xdc.runtime.Log works • Annotated wireless demo screenshots • static screenshots highlighting key capabilities of the wireless application

  34. Tutorial Software Installation • get & extract tutorial zip to any directory (without spaces) • get & install free CCE 3.1: compiler and loader • get & copy LGPL rxtx-2.1-7-bins-r2.zip to ec2009/src/part2/thirdpary/rxtx • get & extract free SimpliciTI CCE 1.1.0 into top of ec2009/src/part2 • get & install free XDCtools 3.15 to any directory • edit both config.bld, common.mak in ec2009/src/part2/examples common.mak: set XDCROOT, CGTOOLS config.bld: set DSSROOT to DebugServer directory in the CCE installation • build all examples cd …/ec2009; $XDCROOT/gmake

  35. Project name: RTSC package name Location: RTSC package base “Low tech” RTSC CDT Integration • Make each RTSC package a distinct CDT standard C/Make project easy to understand, effective, works for all packages in “any” release of Eclipse and CDT • CDT managed make projects can easily use RTSC configurations “simply” incorporate linker.cmd and compiler.opt into your build toolchain options

  36. Use workspace variables or environment variables to define XDCROOT, XDCPATH … The standard make goals work with xdc Building Packages • Replace the default Build command with the xdc command • xdc accepts all GNU make options/goals and automatically tracks all dependencies • Use standard CDT mechanisms to manage XDCPATH and config.bld • workspace variables, environment variables, etc.

  37. ${eclipse_home} eclipse installation directory ${workspace_loc} workspace directory ${project_loc} project directory ${env_var:XDCROOT} ${XDCROOT} environment variable user defined variable Creating “portable” projects • Use variables to define commands or locations without absolute paths • Define custom variables in terms of other variables

  38. Defining Package Build Order Use “Project References” to manage package build order dependencies • in advanced cases, multi-pass builds may still be required but this too can be a CDT project

  39. Setting CDT Project Defaults Use workspace preferences to make these project settings the default • makes it easier to create RTSC project/packages for those who are “RTSC centric”

  40. Importing Entire Repositories • Once created, projects are easily imported to any workspace • Set root directory to a RTSC repository; projects will be recursively found nested packages arenot found however; the search doesn’t descend below an existing project

  41. name the xs command name the xs command if necessary, specify a working directory. if necessary, specify a working directory. specify an XDCtools command and arguments specify an XDCtools command and arguments Running XDCtools Commands Use External Tools to run common XDCtools commands xdc.tools.path.sg to show project’s package path, xdc.tools.cdoc.sg to show package docs, …

  42. Demo Workspace Integration

  43. How Log Works prog.c prog.cfg var Main = xdc.useModule(“xdc.runtime.Main"); var Diags = xdc.useModule(“xdc.runtime.Diags"); var LogUart = xdc.useModule("local.runtime.LogUart"); Main.common$.logger = LogUart.create(); Main.common$.diags_ENTRY = Diags.ALWAYS_ON; #include <xdc/runtime/Log.h> #include <xdc/runtime/Diags.h> int main() { Log_print0(Diags_ENTRY, "…"); return 0; } xdc.runtime #ifndef LOGFXN4 #define LOGFXN4Main_loggerFxn4… #endif local.runtime configuration generated files : const Main_loggerObj =… #define Log_print0(…) \ LOGFXN4(LOGOBJ, … const Main_loggerFnx4 = LogUart LogUart_write4; Log.h int write4() prog_x430.c • Log methods are macros that test the mask before “raising” an event • Log references module logger methods by name • configuration binds the module logger methods to specific functions

  44. How ImplicitLogging Works prog.c #include <pkg/ModA.h> int main() { ModA_start(1, 2); return 0; } • configuration generates “thunks” between caller and callie • when a module’s logger ==NULL (the default), calls are direct prog.cfg var ModA = xdc.useModule(“pkg.ModA"); var Diags = xdc.useModule(“xdc.runtime.Diags"); var LogUart = xdc.useModule("local.runtime.LogUart"); ModA.common$.logger = LogUart.create(); ModA.common$.diags_ENTRY = Diags.ALWAYS_ON; local.runtime configuration generated files pkg ModA : : void start() Int ModA_start__E(…) { ModA.c Log_writeN(…) LogUart r = ModA_start(…) Int ModA_start(…) int write4() { return(…) } Log_write1(…, r) return r; } prog_x430.c

  45. Demo Screen Shots

More Related