// // main loop // int main(void) { #ifdef DEBUG #if __USE_USB usbCDC ser; ser.connect(); #else CSerial ser; ser.settings(115200); #endif CDebug dbg(ser); dbg.start(); #else #undef __USE_USB #endif /************************************************************************* * * your setup code here * **************************************************************************/ // // BLE Engine (Serial Stream) // myBLE ble; ble.advertising(100, -59); // set adv. interval = 100ms, calibrater tx power = -59dBm ble.enable(); // start the ble engine first!! // // Device Information Service // bleDeviceInfo info(ble); info.setManufactureName(u8"英倍達國際"); // u8 mean to use the UTF-8 string info.setModelNumber("nano11U37"); info.setSerialNumber("140226000"); info.setFirmwareRevision(uCXpresso_VER_STR); info.setHardwareRevision("R1"); info.setPnP(VS_USB, 1, 2, 0x3456); // vendor Id=1, product Id = 2, product ver. = 0x3456 SYS_ID_T sysId = { {0x00, 0x01, 0x02, 0x03, 0x04}, // Manufacturer Identifier {0x05, 0x06, 0x07} // Organizationally Unique Identifier }; info.setSystemId(sysId); // // Proximity Service // myProximity alert(ble); // declare Proximity Service (Immediate alert + Lose Link) // // Battery Level Service // bleBatteryLevel bl(ble); // declare Battery Level Service object // // Health Thermometer Service // bleHealthThermometer ht(ble); // declare Health Thermometer Service object ht.measurementInterval(1); // set measurement interval = 1 second // // Arduino Firmata // myFirmata.begin(ble); // begin the Firmata Object with the ble serial stream. callback_init(); // initialize the callback functions for myFirmata Object. // // A key input for Alert (for Proximity) // CPin keyAlert(P8); // define P8 as a push button keyAlert.input(); PIN_LEVEL_T pinVal = keyAlert; // // Timeout for time interval // CTimeout t1, t2, t3; // t1=analog input check, t2=temperature check, t3=battery check #ifndef DEBUG // // Power Save Feature // myPowerSave ps; // use power Save feature #endif float value; uint8_t level; while(1) { /********************************************************************** * * your loop code here * **********************************************************************/ if ( ble.isConnected() ) { #ifndef DEBUG // // Power On // ps.disable(); // disable power save mode #else ledACT = !ledACT; #endif // // UART Service // if ( ble.isAvailable() ) { // // BLE Firmata Demo // if ( myFirmata.available() ) { do { myFirmata.processInput(); } while(myFirmata.available()); } else { // // check the Digital Input // checkDigitalInputs(); // // check the Analog Input with a sampling Interval // if (t1.isExpired(samplingInterval) ) { t1.reset(); checkAnalogInputs(); } } } // // Proximity Service // if ( alert.isAvailable() ) { // // push button check (Proximity Service) // if ( keyAlert != pinVal ) { pinVal = keyAlert; // keep last status of key alert.sendEvent(keyAlert.read()==LOW ? 1 : 0); } } // // Health Thermometer Service // if ( ht.isAvailable() ) { // // check temperature // if ( t2.isExpired(1000) ) { t2.reset(); if ( ht.readTemperature(value) ) { ht.sendMeasure(value); DBG("temp=%0.2f\n", value); } // */ } } // // Battery Service // if ( bl.isAvailable() ) { // // update Battery Level // if ( t3.isExpired(3000) ) { t3.reset(); if ( bl.readSystemVoltage(value) ) { if ( value>=2.4 && value<=3.6 ) { level = map(value, 2.0, 3.3, 0, 100); bl.sendBatteryLevel(level); DBG("battery:%0.2fv %d%c\n", value, level, '%'); } } } } } // isConnected else { #ifndef DEBUG // // Power Save // ps.enable(POWER_DOWN); // enable power save mode #else ledACT = LED_ON; #endif sleep(1000); } } return 0 ; }
/* * Initialise standard routes, logging, configuration, interpret * command line and change directory. * * A standard set of rules is followed to setup the correct * configuration from central places local files and the command line. * All the information is then available in the global CF_VALS: iiab_cf. * The command line config is available in iiab_cmdarg on its own and also * placed in iiab_cf. * There are some standard options implemented by this routine:- * -c Configuration file (arg expected) * -C Configuration option (arg expected) * -d Diagnostic debug mode * -D Developer debug mode * -e 'off the shelf' error format (int arg expected 1-7) * -h Help * -v Version print and exit * Note:- * 1. If the symbol defined by NM_CFNAME (nmalloc) is not defined or * set to 0, nmalloc leak checks are disabled */ void iiab_start(char *opts, /* Command line option string as getopts(3) */ int argc, /* Number of arguments in command line */ char **argv, /* Array of argument strings */ char *usage, /* String describing usage */ char *appcf /* Application configuration string */ ) { int r; char *appcf_expanded; int elogfmt; if ( !(opts && usage) ) elog_die(FATAL, "opts or usage not set"); /* save our launch directory & work out the standard places */ iiab_dir_locations(argv[0]); /* consolidated command line options and usage */ /* -- setup global variables -- */ iiab_cmdopts = util_strjoin(IIAB_DEFOPTS, opts, NULL); iiab_cmdusage = util_strjoin(IIAB_DEFUSAGE, usage, usage?"\n":"", IIAB_DEFWHERE, NULL); iiab_cmdarg = cf_create(); iiab_cf = cf_create(); /* initialise common IIAB classes: callbacks, error logging, * i/o and old storage routes */ callback_init(); iiab_init_routes(); /* initialise new route mechanism */ elog_init(1, argv[0], NULL); rs_init(); /* collect command line arguments and place in special config list * which is use for generating the main config list */ r = cf_cmd(iiab_cmdarg, iiab_cmdopts, argc, argv, iiab_cmdusage); if ( ! r ) { nm_deactivate(); elog_send(FATAL, "incorrect command line, can't continue further"); exit(1); } /* help! print out help before we do anything else and send it * to stderr as the user needs to read it */ if (cf_defined(iiab_cmdarg, "h")) { nm_deactivate(); fprintf(stderr, "usage %s %s", cf_getstr(iiab_cmdarg,"argv0"), iiab_cmdusage); exit(1); } /* load app's dir locations into config, expand the application config * string (which needs the dir locations in iiab_cf), then do the * fullconfig load */ iiab_dir_setcf(iiab_cf); appcf_expanded = nmalloc(strlen(appcf) * 2); route_expand(appcf_expanded, appcf, NULL, 0); iiab_cf_load(iiab_cf, iiab_cmdarg, iiab_cmdusage, appcf_expanded); nfree(appcf_expanded); /*********************************************** * (d) Carry out common configuration actions * 1. configure event logging * 2. memory checking * 3. version switch * 4. adapt logging for -d and -D special debug cases * 5. adapt logging format for -e * 6. final initialisation for subsystems needing configuration * 7. license checking: go/no-go ***********************************************/ /* configure event logging */ elog_configure(iiab_cf); /* * nmalloc deactivation check. * Deactivate nmalloc checking if NM_CFNAME is set to 0 in config */ if ( !cf_defined(iiab_cf, NM_CFNAME) || cf_getint(iiab_cf, NM_CFNAME) == 0 ) nm_deactivate(); /* command line switches (excluding -c and -C) */ /* -v flag: version print and exit */ if (cf_defined(iiab_cmdarg, "v")) { fprintf(stderr, "Version of %s is %s\n", cf_getstr(iiab_cmdarg,"argv0"), VERSION); exit(0); } /* if -d diag flag specified, override supplied event * configuration and instead route DIAG and above to stderr */ if (cf_defined(iiab_cmdarg, "d")) { elog_setallpurl("none:"); elog_setabovepurl(DIAG, "stderr:"); elog_printf(DIAG, "event configuration overidden: diagnosis " "to stderr"); } /* -D debug flag: as above but route everything to stderr */ if (cf_defined(iiab_cmdarg, "D")) { elog_setabovepurl(DEBUG, "stderr:"); elog_printf(DEBUG, "event configuration overidden: debug " "to stderr"); } /* -e flag: use precanned elog formats */ if (cf_defined(iiab_cmdarg, "e")) { elogfmt = cf_getint(iiab_cmdarg, "e"); if (elogfmt < 0 || elogfmt > ELOG_MAXFMT) elog_printf(ERROR, "standard error format out of range " "(0-%d), using default", ELOG_MAXFMT); else elog_setallformat(elog_stdfmt[elogfmt]); } /* diagnostics: config and dirs */ cf_dump(iiab_cf); /* dump config to diag */ iiab_dir_dump(); /* dump dir locations to diag */ /* final set of initialisations that require configurations */ http_init(); #if 0 /* self destruction due to snapshot time out, licenses etc * disabled, but kept here just in case we want to do it again */ if ( ! cf_defined(iiab_cf, IIAB_LICNAME) ) if (time(NULL) > IIAB_EXPIRE) elog_printf(FATAL, "This is development software " "and almost certainly out of date.\n" "You should arrange an update from system garden " "by e-mailing [email protected]\n" "or checking the web site " "http://www.systemgarden.com.\n" "This software will run unaffected in its current " "form but you will be nagged from now on"); #endif #if 0 /* return to the launch dir */ chdir(iiab_dir_launch); #endif }
int main(int argc, char **argv) { time_t now; /* Initialise route, runq and job classes */ now = time(NULL); route_init(NULL, 0); route_register(&rt_filea_method); route_register(&rt_fileov_method); route_register(&rt_stdin_method); route_register(&rt_stdout_method); route_register(&rt_stderr_method); if ( ! elog_init(1, "job test", NULL)) elog_die(FATAL, "didn't initialise elog\n"); sig_init(); callback_init(); runq_init(now); meth_init(); job_init(); /* Test should fail due to incorrect method */ elog_printf(DEBUG, "Expect a complaint! -> "); if (job_add(5, 5, 0, 1, "test1a1", "internal_test", "stdout", "stderr", 100, NULL, "echo \"Hello, world\"") != -1) { elog_die(FATAL, "[1a] Shouldn't be able to add\n"); } /* Single test in five seconds, never to run */ if (job_add(5, 5, 0, 1, "test1a2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1a] Can't add\n"); } /* Attention: some white box testing */ itree_first(runq_event); if (itree_getkey(runq_event) != now+5) { elog_die(FATAL, "[1a] Queued at an incorrect time\n"); } job_clear(); if (!itree_empty(runq_event) || !itree_empty(runq_tab)) { elog_die(FATAL, "[1a] Trees not emptied. runq_events=%d, runq_tab=%d\n", itree_n(runq_event), itree_n(runq_tab)); } now = time(NULL); /* Two tests both in five seconds, never to run */ if (job_add(5, 5, 0, 1, "test1b1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1b] Can't add first\n"); } if (job_add(5, 5, 0, 1, "test1b2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1b] Can't add second\n"); } itree_first(runq_event); if (itree_getkey(runq_event) != now+5) { elog_die(FATAL, "[1b] First queued at an incorrect time\n"); } itree_next(runq_event); if (itree_getkey(runq_event) != now+5) { elog_die(FATAL, "[1b] Second queued at an incorrect time\n"); } job_clear(); if (!itree_empty(runq_event) || !itree_empty(runq_tab)) { elog_die(FATAL, "[1b] Trees not emptied. runq_events=%d, runq_tab=%d\n", itree_n(runq_event), itree_n(runq_tab)); } now = time(NULL); /* Two tests one in five seconds, the other in six, never to run */ if (job_add(6, 6, 0, 1, "test1c1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1c] Can't add first\n"); } if (job_add(now+5, 5, 0, 1, "test1c2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1c] Can't add second\n"); } itree_first(runq_event); if (itree_getkey(runq_event) != now+5) { elog_die(FATAL, "[1c] First queued at an incorrect time\n"); } itree_next(runq_event); if (itree_getkey(runq_event) != now+6) { elog_die(FATAL, "[1c] Second queued at an incorrect time\n"); } job_clear(); if (!itree_empty(runq_event) || !itree_empty(runq_tab)) { elog_die(FATAL, "[1c] Trees not emptied. runq_events=%d, runq_tab=%d\n", itree_n(runq_event), itree_n(runq_tab)); } now = time(NULL); /* Continuous single test supposed to start two seconds ago, * next run in three; never to run */ if (job_add(-2, 5, 0, 0, "test1d1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1d] Can't add\n"); } itree_first(runq_event); if (itree_getkey(runq_event) != now+3) { elog_die(FATAL, "[1d] Event queued at an incorrect time: bad=%d good=%ld\n", itree_getkey(runq_event), now+3); } job_clear(); if (runq_nsched() > 0) { elog_die(FATAL, "[1d] Still active work scheduled. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } now = time(NULL); /* Two continous tests, starting two seconds ago, next next run in four; * never to run */ if (job_add(-2, 6, 0, 0, "test1e1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1e] Can't add first\n"); } if (job_add(-3, 5, 0, 0, "test1e2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1e] Can't add second\n"); } itree_first(runq_event); while (((struct runq_work*) itree_get(runq_event))->expired) itree_next(runq_event); if (itree_getkey(runq_event) != now+2) { elog_die(FATAL, "[1e] First queued at an incorrect time\n"); } itree_next(runq_event); while (((struct runq_work*) itree_get(runq_event))->expired) itree_next(runq_event); if (itree_getkey(runq_event) != now+4) { elog_die(FATAL, "[1e] Second queued at an incorrect time\n"); } job_clear(); if (runq_nsched() > 0) { elog_die(FATAL, "[1e] Still active work scheduled. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } now = time(NULL); /* Two 5 run jobs, scheduled to start 10 seconds ago, with periods * of 5 and 6 seconds; never to run */ if (job_add(-10, 6, 0, 5, "test1f1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1f] Can't add first\n"); } if (job_add(-10, 5, 0, 5, "test1f2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1f] Can't add second\n"); } itree_first(runq_event); while (((struct runq_work*) itree_get(runq_event))->expired) itree_next(runq_event); if (itree_getkey(runq_event) != now+2) { elog_die(FATAL, "[1f] First queued at an incorrect time\n"); } itree_next(runq_event); while (((struct runq_work*) itree_get(runq_event))->expired) itree_next(runq_event); if (itree_getkey(runq_event) != now+5) { elog_die(FATAL, "[1f] Second queued at an incorrect time\n"); } job_clear(); if (runq_nsched() > 0) { elog_die(FATAL, "[1f] Still active work scheduled. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } now = time(NULL); /* Two 5 run jobs, scheduled to start 100 seconds ago, with periods * of 5 and 6 seconds; they should never be scheduled */ if (job_add(-100, 6, 0, 5, "test1g1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1g] Can't add first\n"); } if (job_add(-100, 5, 0, 5, "test1g2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1g] Can't add second\n"); } if (runq_nsched() > 0) { elog_die(FATAL, "[1g] Still active work scheduled. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } job_clear(); now = time(NULL); /* Two five run tests, starting at different times in the past, * five runs each wittth different periods; they should both * run now */ if (job_add(-24, 6, 0, 5, "test1h1", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1h] Can't add first\n"); } if (job_add(-20, 5, 0, 5, "test1h2", "internal_test", "stdout", "stderr", 100, "exec", "echo \"Hello, world\"") == -1) { elog_die(FATAL, "[1h] Can't add second\n"); } if (runq_nsched() != 2) { elog_die(FATAL, "[1h] Two jobs should be scheduled not %d\n", runq_nsched()); runq_dump(); } sig_on(); sleep(6); /* let it run */ sleep(1); /* let it run */ sleep(1); /* let it run */ sleep(1); /* let it run */ sig_off(); if (runq_nsched() > 0) { elog_die(FATAL, "[1h] Still active work scheduled. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } job_clear(); #if 0 /* check all tables/lists are empty */ if (!itree_empty(runq_event) || !itree_empty(runq_tab)) { elog_die(FATAL, "[1i] Still entries in tables. runq_events=%d, " "runq_tab=%d runq_nsched()=%d\n", itree_n(runq_event), itree_n(runq_tab), runq_nsched()); runq_dump(); } #endif job_fini(); meth_fini(); runq_fini(); elog_fini(); route_fini(); callback_fini(); printf("%s: tests finished\n", argv[0]); exit(0); }
// // main loop // int main(void) { #ifdef DEBUG #if __USE_USB usbCDC ser; ser.connect(); #else CSerial ser; ser.settings(115200); #endif CDebug dbg(ser); dbg.start(); #endif // // your setup code here // myBLE ble; ble.enable(128); bleBatteryLevel bl(ble); // declare Battery Level Service object bleHealthThermometer ht(ble); // declare Health Thermometer Service object myFirmata.begin(ble); // begin the Firmata Object with the ble serial stream. callback_init(); // initialize the callback functions for myFirmata Object. CTimeout t1, t2; // t1=battery level update, t2=analog-input interval #ifndef DEBUG myPowerSave ps; // use power Save #endif ledACT = LED_ON; float value; uint8_t level; // // your loop code here // while(1) { if ( ble.isConnected() ) { #ifndef DEBUG ps.disable(); // disable power save mode #endif // // myFirmataClass Check // if ( myFirmata.available() ) { do { myFirmata.processInput(); } while(myFirmata.available()); } else { if ( t1.isExpired(3000)==false ) { // // check the Digital Input // checkDigitalInputs(); // // check the Analog Input with a sampling Interval // if (t2.isExpired(samplingInterval) ) { t2.reset(); checkAnalogInputs(); } } else { t1.reset(); // update Battery Level // if ( bl.readSystemVoltage(value) ) { if ( value>=2.0 && value<=3.6 ) { level = map(value, 2.0, 3.3, 0, 100); bl.sendBatteryLevel(level); DBG("battery:%0.2f %d\n", value, level); } } // // update Temperature // if ( ht.readTemperature(value) ) { ht.sendMeasure(value); DBG("temp=%0.2f\n", value); } // */ } }// */ } else { #ifndef DEBUG ps.enable(POWER_DOWN); // enable power save mode #endif sleep(200); } } return 0 ; }