250 likes | 385 Views
Visual Aspect-Oriented Programming of Resource Constrained Real-Time Embedded Systems using the Port-Based Object Model of Computation. Thomas W. Carley Dept. of Electrical & Computer Engineering University of Maryland, College Park tcarley@eng.umd.edu. David B. Stewart
E N D
Visual Aspect-Oriented Programming ofResource Constrained Real-Time Embedded Systemsusing the Port-Based Object Model of Computation Thomas W. Carley Dept. of Electrical & Computer Engineering University of Maryland, College Park tcarley@eng.umd.edu David B. Stewart Embedded Research Solutions, LLC http://www.embedded-zone.com dstewart@embedded-zone.com
Introduction • Resource Constrained Real-Time Embedded Systems (RCES) • Port-Based Object Model of Computation (PBO MoC) • Separation of Concerns thru Aspect-Oriented Programming (AOP) • Domain Specific Visual Languages (DSVL) for some Aspects
Embedded Systems • Definition • Computer system embedded in another system. • Examples • Personal: watch, pager, cell phone, PDA, smart card. • Home: TV, VCR, set-top box, stereo, appliance, security. • Transportation: automobile, train, plane, traffic control. • Industrial: factory robot, process control, safety monitor. • Military: missile control, remote sensing, communication. • Medical: biometric monitor, pace maker, artificial limb.
Real-Time Systems • A late answer is a wrong answer • Example: Beer Bottling Plant
size cost weight power safety Embedded System Constraints • Physical Constraints • Resulting Resource Constraints • Small & Slow processors • Limited memory • Antiquated development techniques
Port-Based Object (PBO) MoC* • Domain Specific Model for RCES • Formal Syntax • Formal Semantics • Analysis for Real-Time Predictability • Component Based Methodology • PBO Framework • Implementation of PBO Model • Based on hardware * David B. Stewart. Software Components for Real-Time. Embedded Systems Programming, Dec. 2000, vol. 13, no. 13
configuration constants Port-Based Object input ports output ports resource ports (communication with sensors & actuators) PBO Component
PBO Framework PBO init on cycle off term PBO Component & Framework Interface
NOT CREATED spawn term > in-consts init > out-consts term OFF PBO > out-consts init Legend on reinit > in-vars on state of task > in-consts > out-vars call specified method of object out-vars > on cycle off out-vars > block until specified event occurs out-vars > reinit Aperiodic Periodic off signal ON cycle xxx >: copy from local into global state variable table term > in/out > sync term off clock interrupt > in-vars > xxx: copy from global into local state variable table off off wakeup out-vars > out-vars > external signal PBO MoC Semantics
accel engine wheels split-pm control brake ccui dy/dx dashboard position Example PBO Systemcar cruise control
/* =======================================================================// Echidna(tm) RTExec 1.0: FPBO Module// -----------------------------------------------------------------------// Cruise control.// If cruise control is on, this module calculates the force needed// to maintain the reference velocity. If cruise control is off// or the user presses the brakes (override), then this module// passes the direct force through to splitpm.//// State variable table:// INVAR: user_ref v_mez v_ref//// OUTVAR: v_ref f_direct//// ======================================================================= *//* *********************************************************************** // Include files// *********************************************************************** */#include <btypes.h>#include <fpbo.h>/* *********************************************************************** // Local table 'controlLocal_t' and module definition required by Echidna// *********************************************************************** */typedef struct { // Pointers to SVARs go here bool_t *user_ref; // cruise control ON or OFF uint16_t *v_mez; // measured velocity uint16_t *v_ref; // reference velocity for cruise ctrl int16_t *f_direct; // force for acceleration // Pointers to local variables go here etimeAbs_t time_new; etimeAbs_t time_old;} controlLocal_t; // Generate all of the function headers and structures for controlFPBO_MODULE(control);/* *********************************************************************** // FPBO Functions// *********************************************************************** */fpboStatus_t controlInit(control_t *fpbo) { // Map local SVAR pointers to SVARs in the global table fpbo->local->user_ref = svarXlateValue(&fpbo->svartable, "user_ref", bool_t); fpbo->local->v_mez = svarXlateValue(&fpbo->svartable, "v_mez", uint16_t); fpbo->local->v_ref = svarXlateValue(&fpbo->svartable, "v_ref", uint16_t); fpbo->local->f_direct = svarXlateValue(&fpbo->svartable, "f_direct", int16_t); return FPBO_STATUS_CONTINUE;}fpboStatus_t controlReinit(control_t *fpbo) { // This function intentionally left blank. return FPBO_STATUS_CONTINUE;}fpboStatus_t controlOn(control_t *fpbo) { *fpbo->local->f_direct = 0; *fpbo->local->v_ref = 0; etimeClock(&fpbo->local->time_new); return FPBO_STATUS_CONTINUE;}fpboStatus_t controlCycle(control_t *fpbo) { bool_t *user_ref = fpbo->local->user_ref; uint16_t *v_mez = fpbo->local->v_mez; uint16_t *v_ref = fpbo->local->v_ref; int16_t *f_direct = fpbo->local->f_direct; etimeAbs_t *time_new = &fpbo->local->time_new; etimeAbs_t *time_old = &fpbo->local->time_old; //save old time *time_old = *time_new; // get new time etimeClock(time_new); // calculate force needed to maintain ref velocity if cruise is enabled if (*user_ref == FALSE) { // cruise disabled *f_direct = *v_mez / etimeDeltaT(*time_new, *time_old); *v_ref = *v_mez; } else { // cruise enabled *f_direct = (*v_ref - *v_mez) / etimeDeltaT(*time_new, *time_old); } return FPBO_STATUS_CONTINUE;}fpboStatus_t controlSync(control_t *fpbo) { // Define function if FPBO tasktype is aperiodic return FPBO_STATUS_CONTINUE;}fpboStatus_t controlOff(control_t *fpbo) { return FPBO_STATUS_OFF;}fpboStatus_t controlTerm(control_t *fpbo) { return FPBO_STATUS_TERM;} PBO Implementation /* =======================================================================// Echidna(tm) RTExec 1.0: FPBO Module// -----------------------------------------------------------------------// Cruise control.// If cruise control is on, this module calculates the force needed// to maintain the reference velocity. If cruise control is off// or the user presses the brakes (override), then this module// passes the direct force through to splitpm.//// State variable table:// INVAR: user_ref v_mez v_ref//// OUTVAR: v_ref f_direct//// ======================================================================= *//* *********************************************************************** // Include files// *********************************************************************** */#include <btypes.h>#include <fpbo.h>/* *********************************************************************** // Local table 'controlLocal_t' and module definition required by Echidna// *********************************************************************** */typedef struct { // Pointers to SVARs go here bool_t *user_ref; // cruise control ON or OFF uint16_t *v_mez; // measured velocity uint16_t *v_ref; // reference velocity for cruise ctrl int16_t *f_direct; // force for acceleration // Pointers to local variables go here etimeAbs_t time_new; etimeAbs_t time_old;} controlLocal_t; // Generate all of the function headers and structures for controlFPBO_MODULE(control);/* *********************************************************************** // FPBO Functions// *********************************************************************** */fpboStatus_t controlInit(control_t *fpbo) { // Map local SVAR pointers to SVARs in the global table fpbo->local->user_ref = svarXlateValue(&fpbo->svartable, "user_ref", bool_t); fpbo->local->v_mez = svarXlateValue(&fpbo->svartable, "v_mez", uint16_t); fpbo->local->v_ref = svarXlateValue(&fpbo->svartable, "v_ref", uint16_t); fpbo->local->f_direct = svarXlateValue(&fpbo->svartable, "f_direct", int16_t); return FPBO_STATUS_CONTINUE;} fpboStatus_t controlReinit(control_t *fpbo) { // This function intentionally left blank. return FPBO_STATUS_CONTINUE;}fpboStatus_t controlOn(control_t *fpbo) { *fpbo->local->f_direct = 0; *fpbo->local->v_ref = 0; etimeClock(&fpbo->local->time_new); return FPBO_STATUS_CONTINUE;}fpboStatus_t controlCycle(control_t *fpbo) { bool_t *user_ref = fpbo->local->user_ref; uint16_t *v_mez = fpbo->local->v_mez; uint16_t *v_ref = fpbo->local->v_ref; int16_t *f_direct = fpbo->local->f_direct; etimeAbs_t *time_new = &fpbo->local->time_new; etimeAbs_t *time_old = &fpbo->local->time_old; //save old time *time_old = *time_new; // get new time etimeClock(time_new); // calculate force needed to maintain ref velocity if cruise is enabled if (*user_ref == FALSE) { // cruise disabled *f_direct = *v_mez / etimeDeltaT(*time_new, *time_old); *v_ref = *v_mez; } else { // cruise enabled *f_direct = (*v_ref - *v_mez) / etimeDeltaT(*time_new, *time_old); } return FPBO_STATUS_CONTINUE;}fpboStatus_t controlSync(control_t *fpbo) { // Define function if FPBO tasktype is aperiodic return FPBO_STATUS_CONTINUE;}fpboStatus_t controlOff(control_t *fpbo) { return FPBO_STATUS_OFF;}fpboStatus_t controlTerm(control_t *fpbo) { return FPBO_STATUS_TERM;} PBO Framework PBO Communication PBO Implementationusing Traditional Techniques Control Module
/* =======================================================================// Echidna(tm) RTExec 1.0: Main FPBO Module// -----------------------------------------------------------------------// Automobile Speed Control.// Takes input from wheel position resolver, cruise control user// interface, brake pedal, and accelerator pedal. Outputs to // engine, wheels, speedometer, and odometer. Applies different// forces depending on whether cruise control is on or off.//// State variable table:// INVAR: none//// OUTVAR: none//// ======================================================================= *//* *********************************************************************** // Include files// *********************************************************************** */#include <stdlib.h>#include <etime.h>#include <fpbo.h>#include <svar.h>#include <vt.h>/* *********************************************************************** // Internal macro definitions// *********************************************************************** */#define _PERIOD_MAIN ETIME_REL_INFINITY#define _PERIOD_ACCEL 1000 // x0.1 ms#define _PERIOD_BRAKE 1000 // x0.1 ms#define _PERIOD_CCUI 1000 // x0.1 ms#define _PERIOD_POSITION 1000 // x0.1 ms#define _PERIOD_SPLITPM 1000 // x0.1 ms#define _PERIOD_CONTROL 1000 // x0.1 ms#define _PERIOD_TDERIV 1000 // x0.1 ms#define _PERIOD_DASHBOARD 1000 // x0.1 ms#define _PERIOD_ENGINE 1000 // x0.1 ms#define _PERIOD_WHEELS 1000 // x0.1 ms /* *********************************************************************** // Local table 'mainLocal_t' and module definition required by Echidna // *********************************************************************** */ typedef struct { // Pointers to SVARs go here // Pointers to local variables go here fpboSBS_t *sbs; } mainLocal_t; // Generate all of the function headers and structures for main FPBO_MODULE(main); /* *********************************************************************** // External definition of modules for main to create // *********************************************************************** */ FPBO_INCLUDE(accel); FPBO_INCLUDE(brake); FPBO_INCLUDE(ccui); FPBO_INCLUDE(position); FPBO_INCLUDE(tderiv); FPBO_INCLUDE(control); FPBO_INCLUDE(splitpm); FPBO_INCLUDE(engine); FPBO_INCLUDE(wheels); FPBO_INCLUDE(dashboard); /* *********************************************************************** // Pointers to FPBOs for main to create // *********************************************************************** */ fpbo_t *ccui; fpbo_t *position; fpbo_t *tderiv; fpbo_t *control; fpbo_t *dashboard; /* *********************************************************************** // Configurations for FPBOs for main to create // *********************************************************************** */ const fpboCfg_t dashboardFpboCfg = { NULL, // next fpboCfg_t NULL, // list of aliases &dashboardMod, // fpboMod (from FPBO_INCLUDE) "dashboard", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_DASHBOARD // period }; const fpboCfg_t controlFpboCfg = { &dashboardFpboCfg, // next fpboCfg_t NULL, // list of aliases &controlMod, // fpboMod (from FPBO_INCLUDE) "control", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_CONTROL // period }; const fpboCfg_t tderivFpboCfg = { &controlFpboCfg, // next fpboCfg_t NULL, // list of aliases &tderivMod, // fpboMod (from FPBO_INCLUDE) "tderiv", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_TDERIV // period }; const fpboCfg_t positionFpboCfg = { &tderivFpboCfg, // next fpboCfg_t NULL, // list of aliases &positionMod, // fpboMod (from FPBO_INCLUDE) "position", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_POSITION // period }; const fpboCfg_t ccuiFpboCfg = { &positionFpboCfg, // next fpboCfg_t NULL, // list of aliases &ccuiMod, // fpboMod (from FPBO_INCLUDE) "ccui", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_CCUI // period }; const fpboCfg_t mainFpboCfg = { &ccuiFpboCfg, // next fpboCfg_t NULL, // list of aliases &mainMod, // fpboMod (from FPBO_INCLUDE) "main", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_MAIN // period }; /* *********************************************************************** // Linked list of FPBO configurations for main to create // *********************************************************************** */ fpboCfg_t *cfglist = &mainFpboCfg; // points to header of list (main) /* *********************************************************************** // SVAR Attributes for main to place in global SVAR table // *********************************************************************** */ const svarAttrib_t f_brake = { "f_brake", // name VT_UINT16_T, // type 1 // number of elements }; const svarAttrib_t user_ref = { "user_ref", // name VT_BOOL_T, // type 1 // number of elements }; const svarAttrib_t v_mez = { "v_mez", // name VT_UINT16_T, // type 1 // number of elements }; const svarAttrib_t v_ref = { "v_ref", // name VT_UINT16_T, // type 1 // number of elements }; const svarAttrib_t f_direct = { "f_direct", // name VT_INT16_T, // type 1 // number of elements }; const svarAttrib_t x_mez = { "x_mez", // name VT_UINT32_T, // type 1 // number of elements }; /* *********************************************************************** // Array of SVARs for main to place in global SVAR table // *********************************************************************** */ svarVar_t mainSvar[] = { {&f_brake, NULL}, // {svarAttrib_t * attrib, void *value} {&user_ref, NULL}, // {svarAttrib_t * attrib, void *value} {&v_mez, NULL}, // {svarAttrib_t * attrib, void *value} {&v_ref, NULL}, // {svarAttrib_t * attrib, void *value} {&f_direct, NULL}, // {svarAttrib_t * attrib, void *value} {&x_mez, NULL} // {svarAttrib_t * attrib, void *value} }; /* *********************************************************************** // FPBO Functions // *********************************************************************** */ fpboStatus_t mainInit(main_t *fpbo) { fpboSBS_t *sbs = fpbo->local->sbs; svarGlobalTable_t *globt; // Create the SVAR table globt = svarCreate(mainSvar); svarAttach(globt, &fpbo->svartable, fpbo->cfg->aliaslist); // Initialize the subsystem configuration sbs = fpboInitSBS(cfglist, globt); // Create all FPBOs ccui = fpboCreate(sbs, "ccui"); position = fpboCreate(sbs, "position"); tderiv = fpboCreate(sbs, "tderiv"); control = fpboCreate(sbs, "control"); dashboard = fpboCreate(sbs, "dashboard"); return FPBO_STATUS_CONTINUE; } // mainReinit is not defined. Default empty definition fpboStatus_t mainReinit(main_t *fpbo) { // This function intentionally left blank. return FPBO_STATUS_CONTINUE; } fpboStatus_t mainOn(main_t *fpbo) { // Turn on all FPBOs fpboTurnon(ccui); fpboTurnon(position); fpboTurnon(tderiv); fpboTurnon(control); fpboTurnon(dashboard); return FPBO_STATUS_CONTINUE; } // The mainCycle routine monitors various state variables, and // can turn modules on and off as necessary to perform dynamic // reconfiguration. fpboStatus_t mainCycle(main_t *fpbo) { return FPBO_STATUS_CONTINUE; } fpboStatus_t mainSync(main_t *fpbo) { // Define function if FPBO tasktype is aperiodic return FPBO_STATUS_CONTINUE; } fpboStatus_t mainOff(main_t *fpbo) { // Turn off all FPBOs in opposite order of fpboTurnon fpboTurnoff(dashboard); fpboTurnoff(control); fpboTurnoff(tderiv); fpboTurnoff(position); fpboTurnoff(ccui); return FPBO_STATUS_OFF; } // cleanup: destroy the svar table that was created in mainInit fpboStatus_t mainTerm(main_t *fpbo) { // Destroy all FPBOs in opposite order of fpboCreate fpboDestroy(dashboard); fpboDestroy(control); fpboDestroy(tderiv); fpboDestroy(position); fpboDestroy(ccui); // Destroy the SVAR Table svarDestroy(fpbo->local->sbs->globt); return FPBO_STATUS_TERM; } /* =======================================================================// Echidna(tm) RTExec 1.0: Main FPBO Module// -----------------------------------------------------------------------// Automobile Speed Control.// Takes input from wheel position resolver, cruise control user// interface, brake pedal, and accelerator pedal. Outputs to // engine, wheels, speedometer, and odometer. Applies different// forces depending on whether cruise control is on or off.//// State variable table:// INVAR: none//// OUTVAR: none//// ======================================================================= *//* *********************************************************************** // Include files// *********************************************************************** */#include <stdlib.h>#include <etime.h>#include <fpbo.h>#include <svar.h>#include <vt.h>/* *********************************************************************** // Internal macro definitions// *********************************************************************** */#define _PERIOD_MAIN ETIME_REL_INFINITY#define _PERIOD_ACCEL 1000 // x0.1 ms#define _PERIOD_BRAKE 1000 // x0.1 ms#define _PERIOD_CCUI 1000 // x0.1 ms#define _PERIOD_POSITION 1000 // x0.1 ms#define _PERIOD_SPLITPM 1000 // x0.1 ms#define _PERIOD_CONTROL 1000 // x0.1 ms#define _PERIOD_TDERIV 1000 // x0.1 ms#define _PERIOD_DASHBOARD 1000 // x0.1 ms#define _PERIOD_ENGINE 1000 // x0.1 ms#define _PERIOD_WHEELS 1000 // x0.1 ms /* *********************************************************************** // Local table 'mainLocal_t' and module definition required by Echidna // *********************************************************************** */ typedef struct { // Pointers to SVARs go here // Pointers to local variables go here fpboSBS_t *sbs; } mainLocal_t; // Generate all of the function headers and structures for main FPBO_MODULE(main); /* *********************************************************************** // External definition of modules for main to create // *********************************************************************** */ FPBO_INCLUDE(accel); FPBO_INCLUDE(brake); FPBO_INCLUDE(ccui); FPBO_INCLUDE(position); FPBO_INCLUDE(tderiv); FPBO_INCLUDE(control); FPBO_INCLUDE(splitpm); FPBO_INCLUDE(engine); FPBO_INCLUDE(wheels); FPBO_INCLUDE(dashboard); /* *********************************************************************** // Pointers to FPBOs for main to create // *********************************************************************** */ fpbo_t *ccui; fpbo_t *position; fpbo_t *tderiv; fpbo_t *control; fpbo_t *dashboard; /* *********************************************************************** // Configurations for FPBOs for main to create // *********************************************************************** */ const fpboCfg_t dashboardFpboCfg = { NULL, // next fpboCfg_t NULL, // list of aliases &dashboardMod, // fpboMod (from FPBO_INCLUDE) "dashboard", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_DASHBOARD // period }; const fpboCfg_t controlFpboCfg = { &dashboardFpboCfg, // next fpboCfg_t NULL, // list of aliases &controlMod, // fpboMod (from FPBO_INCLUDE) "control", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_CONTROL // period }; const fpboCfg_t tderivFpboCfg = { &controlFpboCfg, // next fpboCfg_t NULL, // list of aliases &tderivMod, // fpboMod (from FPBO_INCLUDE) "tderiv", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_TDERIV // period }; const fpboCfg_t positionFpboCfg = { &tderivFpboCfg, // next fpboCfg_t NULL, // list of aliases &positionMod, // fpboMod (from FPBO_INCLUDE) "position", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_POSITION // period }; const fpboCfg_t ccuiFpboCfg = { &positionFpboCfg, // next fpboCfg_t NULL, // list of aliases &ccuiMod, // fpboMod (from FPBO_INCLUDE) "ccui", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_CCUI // period }; const fpboCfg_t mainFpboCfg = { &ccuiFpboCfg, // next fpboCfg_t NULL, // list of aliases &mainMod, // fpboMod (from FPBO_INCLUDE) "main", // name of fpbo PERIODIC, // tasktype (PERIODIC, APERIODIC) _PERIOD_MAIN // period }; /* *********************************************************************** // Linked list of FPBO configurations for main to create // *********************************************************************** */ fpboCfg_t *cfglist = &mainFpboCfg; // points to header of list (main) /* *********************************************************************** // SVAR Attributes for main to place in global SVAR table // *********************************************************************** */ const svarAttrib_t f_brake = { "f_brake", // name VT_UINT16_T, // type 1 // number of elements }; const svarAttrib_t user_ref = { "user_ref", // name VT_BOOL_T, // type 1 // number of elements }; const svarAttrib_t v_mez = { "v_mez", // name VT_UINT16_T, // type 1 // number of elements }; const svarAttrib_t v_ref = { "v_ref", // name VT_UINT16_T, // type 1 // number of elements }; const svarAttrib_t f_direct = { "f_direct", // name VT_INT16_T, // type 1 // number of elements }; const svarAttrib_t x_mez = { "x_mez", // name VT_UINT32_T, // type 1 // number of elements }; /* *********************************************************************** // Array of SVARs for main to place in global SVAR table // *********************************************************************** */ svarVar_t mainSvar[] = { {&f_brake, NULL}, // {svarAttrib_t * attrib, void *value} {&user_ref, NULL}, // {svarAttrib_t * attrib, void *value} {&v_mez, NULL}, // {svarAttrib_t * attrib, void *value} {&v_ref, NULL}, // {svarAttrib_t * attrib, void *value} {&f_direct, NULL}, // {svarAttrib_t * attrib, void *value} {&x_mez, NULL} // {svarAttrib_t * attrib, void *value} }; /* *********************************************************************** // FPBO Functions // *********************************************************************** */ fpboStatus_t mainInit(main_t *fpbo) { fpboSBS_t *sbs = fpbo->local->sbs; svarGlobalTable_t *globt; // Create the SVAR table globt = svarCreate(mainSvar); svarAttach(globt, &fpbo->svartable, fpbo->cfg->aliaslist); // Initialize the subsystem configuration sbs = fpboInitSBS(cfglist, globt); // Create all FPBOs ccui = fpboCreate(sbs, "ccui"); position = fpboCreate(sbs, "position"); tderiv = fpboCreate(sbs, "tderiv"); control = fpboCreate(sbs, "control"); dashboard = fpboCreate(sbs, "dashboard"); return FPBO_STATUS_CONTINUE; } // mainReinit is not defined. Default empty definition fpboStatus_t mainReinit(main_t *fpbo) { // This function intentionally left blank. return FPBO_STATUS_CONTINUE; } fpboStatus_t mainOn(main_t *fpbo) { // Turn on all FPBOs fpboTurnon(ccui); fpboTurnon(position); fpboTurnon(tderiv); fpboTurnon(control); fpboTurnon(dashboard); return FPBO_STATUS_CONTINUE; } // The mainCycle routine monitors various state variables, and // can turn modules on and off as necessary to perform dynamic // reconfiguration. fpboStatus_t mainCycle(main_t *fpbo) { return FPBO_STATUS_CONTINUE; } fpboStatus_t mainSync(main_t *fpbo) { // Define function if FPBO tasktype is aperiodic return FPBO_STATUS_CONTINUE; } fpboStatus_t mainOff(main_t *fpbo) { // Turn off all FPBOs in opposite order of fpboTurnon fpboTurnoff(dashboard); fpboTurnoff(control); fpboTurnoff(tderiv); fpboTurnoff(position); fpboTurnoff(ccui); return FPBO_STATUS_OFF; } // cleanup: destroy the svar table that was created in mainInit fpboStatus_t mainTerm(main_t *fpbo) { // Destroy all FPBOs in opposite order of fpboCreate fpboDestroy(dashboard); fpboDestroy(control); fpboDestroy(tderiv); fpboDestroy(position); fpboDestroy(ccui); // Destroy the SVAR Table svarDestroy(fpbo->local->sbs->globt); return FPBO_STATUS_TERM; } PBO Implementation PBO Framework PBO Communication PBO System Configurationusing Traditional Techniques
Difficulties Programming the PBO MoC • Framework visible to programmer • Framework distributed across PBOs • PBO not portable across frameworks • Implementation tangled • Data Types, Algorithms, Framework, Communication, Scheduling, Resource Management, etc. Solution: Aspect-Oriented Programming
Aspect-Oriented Programming • Separation of Concerns • Aspects of a system that are designed separately should be accessed separately. • Aspect Languages • Algorithmic, Visual, Tabular, etc. • Weave together forfinal implementation
Different Aspects for Different Programmers • Control Engineer is concerned with the implementation of the control algorithm. • Systems Integrator is concerned with component specifications and interfaces. • Real-Time System Engineer is concerned with the task management information such as task period, deadline, and execution time. Recall cruise control example
Aspects for RCES & PBO MoC • PBO Component Design • Control Engineer • PBO System Design • System Integrator • PBO Instance Management • Real-Time System Engineer • Memory Management • Power Management • Device Driver • Error Detection & Handling
PBO PBO Component DesignAlgorithmic Aspect • PBO Interface • Specify Input & output ports • PBO Implementation • Specify local data & types • Implement PBO methods • Algorithmic Language • Use existing C compilers /* =======================================================================// Echidna(tm) RTExec 1.0: FPBO Module// -----------------------------------------------------------------------// Cruise control.// If cruise control is on, this module calculates the force needed// to maintain the reference velocity. If cruise control is off// or the user presses the brakes (override), then this module// passes the direct force through to splitpm.//// State variable table:// INVAR: user_ref v_mez v_ref//// OUTVAR: v_ref f_direct//// ======================================================================= *//* *********************************************************************** // Include files// *********************************************************************** */#include <btypes.h>#include <fpbo.h>/* *********************************************************************** // Local table 'controlLocal_t' and module definition required by Echidna// *********************************************************************** */typedef struct { // Pointers to SVARs go here bool_t *user_ref; // cruise control ON or OFF uint16_t *v_mez; // measured velocity uint16_t *v_ref; // reference velocity for cruise ctrl int16_t *f_direct; // force for acceleration // Pointers to local variables go here etimeAbs_t time_new; etimeAbs_t time_old;} controlLocal_t; // Generate all of the function headers and structures for controlFPBO_MODULE(control);/* *********************************************************************** // FPBO Functions// *********************************************************************** */fpboStatus_t controlInit(control_t *fpbo) { // Map local SVAR pointers to SVARs in the global table fpbo->local->user_ref = svarXlateValue(&fpbo->svartable, "user_ref", bool_t); fpbo->local->v_mez = svarXlateValue(&fpbo->svartable, "v_mez", uint16_t); fpbo->local->v_ref = svarXlateValue(&fpbo->svartable, "v_ref", uint16_t); fpbo->local->f_direct = svarXlateValue(&fpbo->svartable, "f_direct", int16_t); return FPBO_STATUS_CONTINUE;}
accel engine wheels split-pm control brake ccui dy/dx dashboard position PBO System DesignVisual Aspect
Aspect Weaver • Synthesize each PBO Implementation • Create PBO Instances • Implement PBOCommunication • Synthesize PBO Framework • Task Scheduler • Communication Mechanism