research application on sending data to headend
Dependencies: DataStore JobScheduler NetworkServices W5500Interface nanopb protocol
See "main.cpp" documentation on "API Documentation" tab for details about application.
source/main.cpp@22:3af582d8e227, 2017-08-04 (annotated)
- Committer:
- sgnezdov
- Date:
- Fri Aug 04 21:08:49 2017 +0000
- Revision:
- 22:3af582d8e227
- Parent:
- 21:32cd3bfde206
added application level documentation (high level design)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sgnezdov | 0:2c57ed6943f7 | 1 | #include "mbed.h" |
sgnezdov | 0:2c57ed6943f7 | 2 | |
sgnezdov | 0:2c57ed6943f7 | 3 | #include "mbed-trace/mbed_trace.h" |
sgnezdov | 0:2c57ed6943f7 | 4 | #define TRACE_GROUP "main" |
sgnezdov | 0:2c57ed6943f7 | 5 | |
sgnezdov | 1:eebe442fc126 | 6 | #include "scheduler.h" |
sgnezdov | 1:eebe442fc126 | 7 | #include "schedules.h" |
sgnezdov | 1:eebe442fc126 | 8 | #include "jobService.h" |
sgnezdov | 4:b360d4f0bf34 | 9 | #include "netstack.h" |
sgnezdov | 13:0fdbc14c33e7 | 10 | #include "config.h" |
sgnezdov | 4:b360d4f0bf34 | 11 | #include "lceProxy.h" |
sgnezdov | 4:b360d4f0bf34 | 12 | |
sgnezdov | 1:eebe442fc126 | 13 | #include "jobTestPrint.h" |
sgnezdov | 4:b360d4f0bf34 | 14 | #include "jobFakeADC.h" |
sgnezdov | 11:acaefb63fc6b | 15 | #include "jobSchedulesUpload.h" |
sgnezdov | 16:bef1673b199e | 16 | #include "jobTestUpload.h" |
sgnezdov | 1:eebe442fc126 | 17 | |
sgnezdov | 22:3af582d8e227 | 18 | /** TracingLock provides a single synhronization point for tracing library. */ |
sgnezdov | 0:2c57ed6943f7 | 19 | static Mutex TracingLock; |
sgnezdov | 22:3af582d8e227 | 20 | |
sgnezdov | 22:3af582d8e227 | 21 | /** @brief Implements trace library locking policy, which is to synchronize its output. */ |
sgnezdov | 0:2c57ed6943f7 | 22 | static void tracingWait() |
sgnezdov | 0:2c57ed6943f7 | 23 | { |
sgnezdov | 0:2c57ed6943f7 | 24 | TracingLock.lock(); |
sgnezdov | 0:2c57ed6943f7 | 25 | } |
sgnezdov | 22:3af582d8e227 | 26 | |
sgnezdov | 22:3af582d8e227 | 27 | /** @brief Implements tracing library release policy. */ |
sgnezdov | 0:2c57ed6943f7 | 28 | static void tracingRelease() |
sgnezdov | 0:2c57ed6943f7 | 29 | { |
sgnezdov | 0:2c57ed6943f7 | 30 | TracingLock.unlock(); |
sgnezdov | 0:2c57ed6943f7 | 31 | } |
sgnezdov | 0:2c57ed6943f7 | 32 | |
sgnezdov | 9:d6a9210bfd41 | 33 | static bool initTime() |
sgnezdov | 9:d6a9210bfd41 | 34 | { |
sgnezdov | 9:d6a9210bfd41 | 35 | struct tm clock; |
sgnezdov | 9:d6a9210bfd41 | 36 | clock.tm_year = 2001 - 1900; |
sgnezdov | 9:d6a9210bfd41 | 37 | clock.tm_mon = 0; |
sgnezdov | 9:d6a9210bfd41 | 38 | clock.tm_mday = 1; |
sgnezdov | 9:d6a9210bfd41 | 39 | clock.tm_hour = 13; |
sgnezdov | 9:d6a9210bfd41 | 40 | clock.tm_min = 30; |
sgnezdov | 9:d6a9210bfd41 | 41 | clock.tm_sec = 0; |
sgnezdov | 9:d6a9210bfd41 | 42 | // time_t is in seconds |
sgnezdov | 9:d6a9210bfd41 | 43 | time_t time = mktime(&clock); |
sgnezdov | 9:d6a9210bfd41 | 44 | if (time == (time_t) - 1) { |
sgnezdov | 9:d6a9210bfd41 | 45 | error("Error setting clock."); |
sgnezdov | 9:d6a9210bfd41 | 46 | return false; |
sgnezdov | 9:d6a9210bfd41 | 47 | } |
sgnezdov | 9:d6a9210bfd41 | 48 | set_time(time); |
sgnezdov | 9:d6a9210bfd41 | 49 | printf("Time is set to: %s\n", ctime(&time)); |
sgnezdov | 9:d6a9210bfd41 | 50 | return true; |
sgnezdov | 9:d6a9210bfd41 | 51 | } |
sgnezdov | 9:d6a9210bfd41 | 52 | |
sgnezdov | 22:3af582d8e227 | 53 | /** |
sgnezdov | 22:3af582d8e227 | 54 | \brief Application entry point. |
sgnezdov | 22:3af582d8e227 | 55 | |
sgnezdov | 22:3af582d8e227 | 56 | Main up execution environment. |
sgnezdov | 22:3af582d8e227 | 57 | |
sgnezdov | 22:3af582d8e227 | 58 | Sets up tracing environment to be thread safe. |
sgnezdov | 22:3af582d8e227 | 59 | |
sgnezdov | 22:3af582d8e227 | 60 | Initializes services such as networking stack, LCE proxy and others. |
sgnezdov | 22:3af582d8e227 | 61 | |
sgnezdov | 22:3af582d8e227 | 62 | Configures and starts scheduler service that's at the core of the application |
sgnezdov | 22:3af582d8e227 | 63 | functinality and design. |
sgnezdov | 22:3af582d8e227 | 64 | |
sgnezdov | 22:3af582d8e227 | 65 | Associates job type IDs with functions that implement high level job concept. |
sgnezdov | 22:3af582d8e227 | 66 | |
sgnezdov | 22:3af582d8e227 | 67 | If you need to add new functionality create it a a standalone C function |
sgnezdov | 22:3af582d8e227 | 68 | or C++ adapter function backed by C++ object state and register it with |
sgnezdov | 22:3af582d8e227 | 69 | scheduler service registry. |
sgnezdov | 22:3af582d8e227 | 70 | |
sgnezdov | 22:3af582d8e227 | 71 | Some jobs can be created in the main to bootstrap application functionality. |
sgnezdov | 22:3af582d8e227 | 72 | |
sgnezdov | 22:3af582d8e227 | 73 | Piggybacked commands can change internal scheduler state by adding new jobs |
sgnezdov | 22:3af582d8e227 | 74 | or removing existing jobs. |
sgnezdov | 22:3af582d8e227 | 75 | |
sgnezdov | 22:3af582d8e227 | 76 | @see main.h for design details. |
sgnezdov | 21:32cd3bfde206 | 77 | */ |
sgnezdov | 0:2c57ed6943f7 | 78 | int main() |
sgnezdov | 0:2c57ed6943f7 | 79 | { |
sgnezdov | 12:ec140a26367f | 80 | Serial pc(USBTX, USBRX); |
sgnezdov | 12:ec140a26367f | 81 | pc.baud(115200); |
sgnezdov | 12:ec140a26367f | 82 | |
sgnezdov | 0:2c57ed6943f7 | 83 | printf("\n==Borsch==\n"); |
sgnezdov | 9:d6a9210bfd41 | 84 | |
sgnezdov | 9:d6a9210bfd41 | 85 | // if (initTime() == false) { |
sgnezdov | 11:acaefb63fc6b | 86 | // printf("Application terminated: initTime has failed\n"); |
sgnezdov | 9:d6a9210bfd41 | 87 | // exit(1); |
sgnezdov | 9:d6a9210bfd41 | 88 | // } |
sgnezdov | 9:d6a9210bfd41 | 89 | |
sgnezdov | 0:2c57ed6943f7 | 90 | /* Setup tracing */ |
sgnezdov | 0:2c57ed6943f7 | 91 | mbed_trace_mutex_wait_function_set( tracingWait ); // only if thread safety is needed |
sgnezdov | 0:2c57ed6943f7 | 92 | mbed_trace_mutex_release_function_set( tracingRelease ); // only if thread safety is needed |
sgnezdov | 0:2c57ed6943f7 | 93 | mbed_trace_init(); // initialize the trace library |
sgnezdov | 0:2c57ed6943f7 | 94 | |
sgnezdov | 13:0fdbc14c33e7 | 95 | tr_info("**Started**"); //-> "[INFO][main]: this is an info msg" |
sgnezdov | 17:b79ce8109995 | 96 | osThreadId_t tid = osThreadGetId(); |
sgnezdov | 17:b79ce8109995 | 97 | tr_debug("Main thread ID: 0x%X", tid); |
sgnezdov | 13:0fdbc14c33e7 | 98 | |
sgnezdov | 13:0fdbc14c33e7 | 99 | Config conf("Nucleo1"); |
sgnezdov | 2:661c545d718e | 100 | |
sgnezdov | 9:d6a9210bfd41 | 101 | uint8_t mac_addr[6] = {0x00, 0x08, 0xdc, 0x45, 0x56, 0x67}; |
sgnezdov | 2:661c545d718e | 102 | NetworkInterface* nif = initNetworkStack(mac_addr); |
sgnezdov | 2:661c545d718e | 103 | if (nif == NULL) { |
sgnezdov | 2:661c545d718e | 104 | tr_error("**Terminated**"); |
sgnezdov | 2:661c545d718e | 105 | exit(0); |
sgnezdov | 2:661c545d718e | 106 | } |
sgnezdov | 0:2c57ed6943f7 | 107 | |
sgnezdov | 16:bef1673b199e | 108 | LceProxy lce(*nif, conf); |
sgnezdov | 4:b360d4f0bf34 | 109 | |
sgnezdov | 1:eebe442fc126 | 110 | JobScheduler::JobService js; |
sgnezdov | 1:eebe442fc126 | 111 | JobScheduler::Scheduler scheduler(&js); |
sgnezdov | 1:eebe442fc126 | 112 | |
sgnezdov | 11:acaefb63fc6b | 113 | /* Job Type ID shall match command id defined in ISOM commandTypes.go |
sgnezdov | 11:acaefb63fc6b | 114 | While this rule is not strictly necessary it cuts down on code responsible |
sgnezdov | 11:acaefb63fc6b | 115 | for mapping between our internal IDs to CommandIDs. |
sgnezdov | 11:acaefb63fc6b | 116 | |
sgnezdov | 11:acaefb63fc6b | 117 | addKV(NewCommandMetaData(1, "NO-OP")) |
sgnezdov | 11:acaefb63fc6b | 118 | addKV(NewCommandMetaData(2, "List Schedules")) |
sgnezdov | 11:acaefb63fc6b | 119 | addKV(NewCommandMetaData(3, "Add Schedule")) |
sgnezdov | 11:acaefb63fc6b | 120 | addKV(NewCommandMetaData(4, "Remove Schedule")) |
sgnezdov | 11:acaefb63fc6b | 121 | addKV(NewCommandMetaData(5, "Set STM ADC Schedule")) |
sgnezdov | 11:acaefb63fc6b | 122 | addKV(NewCommandMetaData(31, "Close Valve")) |
sgnezdov | 11:acaefb63fc6b | 123 | addKV(NewCommandMetaData(32, "Open Valve")) |
sgnezdov | 11:acaefb63fc6b | 124 | |
sgnezdov | 11:acaefb63fc6b | 125 | Use range 1000 for unique to STM jobs. |
sgnezdov | 11:acaefb63fc6b | 126 | */ |
sgnezdov | 11:acaefb63fc6b | 127 | |
sgnezdov | 11:acaefb63fc6b | 128 | // command #2 is List Schedules in ISOM. |
sgnezdov | 13:0fdbc14c33e7 | 129 | JobSchedulesUpload jSchedulesUpload(conf, lce, scheduler); |
sgnezdov | 11:acaefb63fc6b | 130 | js.Register(2, JobSchedulesUpload::RunAdapter, &jSchedulesUpload); |
sgnezdov | 11:acaefb63fc6b | 131 | |
sgnezdov | 16:bef1673b199e | 132 | JobTestPrint jTestPrint; |
sgnezdov | 16:bef1673b199e | 133 | js.Register(1001, JobTestPrint::RunAdapter, &jTestPrint); |
sgnezdov | 4:b360d4f0bf34 | 134 | |
sgnezdov | 16:bef1673b199e | 135 | JobFakeADC jFakeADC(lce); |
sgnezdov | 16:bef1673b199e | 136 | js.Register(1002, JobFakeADC::RunAdapter, &jFakeADC); |
sgnezdov | 16:bef1673b199e | 137 | |
sgnezdov | 16:bef1673b199e | 138 | JobTestUpload jTestUpload(lce); |
sgnezdov | 16:bef1673b199e | 139 | js.Register(1003, JobTestUpload::RunAdapter, &jTestUpload); |
sgnezdov | 0:2c57ed6943f7 | 140 | |
sgnezdov | 1:eebe442fc126 | 141 | scheduler.Start(); |
sgnezdov | 1:eebe442fc126 | 142 | |
sgnezdov | 1:eebe442fc126 | 143 | // inject test case |
sgnezdov | 1:eebe442fc126 | 144 | time_t nowSecs = time(NULL); |
sgnezdov | 7:c4123a87abe2 | 145 | // NOTE: don't schedule run once with at 0, because 0 means never. |
sgnezdov | 16:bef1673b199e | 146 | //JobScheduler::Response<JobScheduler::JobID> res = |
sgnezdov | 20:5b52a42b9a5d | 147 | scheduler.JobAdd(1001, new JobScheduler::RunOnceSchedule(nowSecs+31), NULL); |
sgnezdov | 20:5b52a42b9a5d | 148 | scheduler.JobAdd(1001, new JobScheduler::RunOnceSchedule(nowSecs+32), NULL); |
sgnezdov | 20:5b52a42b9a5d | 149 | scheduler.JobAdd(1001, new JobScheduler::RunOnceSchedule(nowSecs+33), NULL); |
sgnezdov | 20:5b52a42b9a5d | 150 | scheduler.JobAdd(2, new JobScheduler::RunOnceSchedule(nowSecs), NULL); |
sgnezdov | 20:5b52a42b9a5d | 151 | // |
sgnezdov | 20:5b52a42b9a5d | 152 | // scheduler.JobAdd(2, new JobScheduler::RunPeriodicSchedule(10, 3), NULL); |
sgnezdov | 20:5b52a42b9a5d | 153 | // scheduler.JobAdd(1001, new JobScheduler::RunPeriodicSchedule(5, 10), NULL); |
sgnezdov | 19:40f5bcec121e | 154 | |
sgnezdov | 11:acaefb63fc6b | 155 | //scheduler.JobAdd(1002, new JobScheduler::RunOnceSchedule(1), NULL); |
sgnezdov | 11:acaefb63fc6b | 156 | //scheduler.JobAdd(1001, new JobScheduler::RunOnceSchedule(nowSecs + 2), NULL); |
sgnezdov | 11:acaefb63fc6b | 157 | //res = scheduler.JobAdd(1002, new JobScheduler::RunPeriodicSchedule(2, 5), NULL); |
sgnezdov | 1:eebe442fc126 | 158 | |
sgnezdov | 1:eebe442fc126 | 159 | // block forever unless there is a job that calls scheduler.Stop() |
sgnezdov | 1:eebe442fc126 | 160 | scheduler.WaitToStop(); |
sgnezdov | 1:eebe442fc126 | 161 | |
sgnezdov | 4:b360d4f0bf34 | 162 | /* we can somehow load new application image here and restart */ |
sgnezdov | 4:b360d4f0bf34 | 163 | |
sgnezdov | 1:eebe442fc126 | 164 | // indicate clean app termination |
sgnezdov | 0:2c57ed6943f7 | 165 | tr_info("**Finished**"); //-> "[INFO][main]: this is an info msg" |
sgnezdov | 0:2c57ed6943f7 | 166 | exit(0); |
sgnezdov | 0:2c57ed6943f7 | 167 | } |