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.

Committer:
sgnezdov
Date:
Fri Aug 11 19:07:20 2017 +0000
Revision:
28:7214f7806526
Parent:
26:1798e352679a
fixed compilation bug

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sgnezdov 22:3af582d8e227 1 #pragma once
sgnezdov 22:3af582d8e227 2
sgnezdov 22:3af582d8e227 3 // Include main application documentation.
sgnezdov 22:3af582d8e227 4 /**
sgnezdov 22:3af582d8e227 5
sgnezdov 22:3af582d8e227 6 @file main.cpp
sgnezdov 22:3af582d8e227 7
sgnezdov 22:3af582d8e227 8 @brief Contains application entry point and oulines core application design.
sgnezdov 22:3af582d8e227 9
sgnezdov 25:65e430b98cbe 10 @section s_design_overview Design Overview
sgnezdov 22:3af582d8e227 11
sgnezdov 24:62ca1f410862 12 The application is designed around the concept of serial execution of high level tasks called jobs. The 'scheduler' library is responsible for maintaining job schedules and ensuring that only one job is executing at any given time. See Scheduler library for details related to order of execution and scheduling.
sgnezdov 22:3af582d8e227 13
sgnezdov 24:62ca1f410862 14 Each job is defined as a function that needs to be executed. Currently the job function does not take any arguments. It is planned that job may take a single argument of Scheduler::Appointment type. Appointment provides scheduler oriented details about the job and job instance specific configuration parameters.
sgnezdov 22:3af582d8e227 15
sgnezdov 24:62ca1f410862 16 Each job has its own unique context that's defined by its dependency on application specific services. Application service is a cohesively defined application feature. Examples of application services:
sgnezdov 22:3af582d8e227 17
sgnezdov 22:3af582d8e227 18 @li LCE is a lightweight collection engine proxy. LCE provides interface for sending CoAP data to headend (HE).
sgnezdov 22:3af582d8e227 19
sgnezdov 22:3af582d8e227 20 @li Configuration service collects device specific configuration such as Serial Number and other parameters that can be changed through commands while device is running.
sgnezdov 22:3af582d8e227 21
sgnezdov 22:3af582d8e227 22 @li Network stack service is defined by mbed OS itself through NetworkInterface class. NetworkInterface is a good example of changing application functionality through change of interface implementation. For example, it can use W5500 driver and it can be use a cell modem driver.
sgnezdov 22:3af582d8e227 23
sgnezdov 22:3af582d8e227 24 @li Scheduler is a service object from design level point of view. Scheduler can be passed as a context dependency to jobs that need to manipulate schedules.
sgnezdov 22:3af582d8e227 25
sgnezdov 24:62ca1f410862 26 In the modern application design internal application service is usually defined as an interface. That interface then has production level implementation and may have test level mock implementations. While Borsch is not specifically designed with this purpose in mind, it does not preclude the model.
sgnezdov 22:3af582d8e227 27
sgnezdov 24:62ca1f410862 28 Service objects are expected to be not NULL. Failure to create a service object results in application termination as it results in cascading failure effect.
sgnezdov 22:3af582d8e227 29
sgnezdov 24:62ca1f410862 30 If job is implemented as a C++ class, then its service references should be instance variables. C++ 'reference' is recommended instead of pointer, because services are always expected to be not NULL. If a particular service can be NULL, then recommendation does not apply.
sgnezdov 24:62ca1f410862 31 If job is implemented as a C module, then a separate initialize function is expected to set module level dependency variables.
sgnezdov 22:3af582d8e227 32
sgnezdov 23:1976f83da84e 33 @subsection do_application_lifetime Application Lifetime
sgnezdov 22:3af582d8e227 34
sgnezdov 22:3af582d8e227 35 Once service objects are created, job scheduler is started on the main application thread. Main thread is then blocked by waiting for scheduler to quit. Unless there is a job that explicitly requests scheduler termination, the main thread will never unblock.
sgnezdov 22:3af582d8e227 36
sgnezdov 24:62ca1f410862 37 If scheduler stops, then main thread proceeds to the final stage of the application. At this stage it is guaranteed that no job will be running and no new job can be started, because scheduler has been stopped. Thus, environment is fully under the main() function control and drastic changes can be applied such as firmware upgrades.
sgnezdov 22:3af582d8e227 38
sgnezdov 26:1798e352679a 39 @subsection do_job_lifetime Job Lifetime
sgnezdov 26:1798e352679a 40
sgnezdov 26:1798e352679a 41 Job is a simple C function that executes as C module function or that acts as an adapter to C++ method.
sgnezdov 26:1798e352679a 42
sgnezdov 26:1798e352679a 43 The simplest job is a function that does nothing. A slightly more complicated job can just print "Hello, world!".
sgnezdov 26:1798e352679a 44
sgnezdov 26:1798e352679a 45 Job scheduler calls the function when it is time to execute it. Job scheduler guarantees that no other job can be running at the same time. Job scheduler takes care of make sure that job function is called again according to assigned schedule.
sgnezdov 26:1798e352679a 46
sgnezdov 26:1798e352679a 47 Job scheduler does not guarantee that job will be started at exactly the requested time. If you want to make sure that job is started at the right time make sure you don't schedule more than one job for the same time or schedule 2 jobs too close to each other. Thus, the responsibility of ensuring that job starts at the right time sits at higher level with person how creates the overall schedule for all jobs.
sgnezdov 26:1798e352679a 48
sgnezdov 26:1798e352679a 49 The next job run time is calculated by the scheduler after job function returns.
sgnezdov 26:1798e352679a 50
sgnezdov 26:1798e352679a 51 In the future, when job takes Scheduler::Appointment data structure as an argument, the job will be able to dynamically modify its schedule. For example, the following scenario will be possible. Job is started with run once schedule. Run once schedule ensures that job runs only once. Prior to returning job can set new RunOnce schedule and thus have a variable business dependent timing with little added complexity.
sgnezdov 26:1798e352679a 52
sgnezdov 23:1976f83da84e 53 @subsection do_parallel_to_jobs Running of Other Parallel Threads
sgnezdov 22:3af582d8e227 54
sgnezdov 22:3af582d8e227 55 The job is just another C function and thus there is nothing to stop function from creating its own thread after execution ends. This is not denied, but a high level impact needs to be considered.
sgnezdov 22:3af582d8e227 56
sgnezdov 22:3af582d8e227 57 For example, a receiving thread can be started for the life time of the socket.
sgnezdov 22:3af582d8e227 58
sgnezdov 22:3af582d8e227 59 One consequence to consider is that creation of long running threads that go beyond job lifetime will make it more difficult to manage power consumption. The recommended solution is to schedule another job through application scheduler from the job function itself. This way a single task at a time concept is not impacted and there is no concurrency complication.
sgnezdov 24:62ca1f410862 60
sgnezdov 25:65e430b98cbe 61 @section s_tracing Tracing
sgnezdov 25:65e430b98cbe 62
sgnezdov 25:65e430b98cbe 63 Application relies on mbed OS tracing functionality to make it easier to debug modules.
sgnezdov 25:65e430b98cbe 64
sgnezdov 25:65e430b98cbe 65 References:
sgnezdov 25:65e430b98cbe 66
sgnezdov 25:65e430b98cbe 67 @li http://www.emcu.eu/wp-content/uploads/2017/06/07-HandsOn-Part-3-Debugging-And-Tracing.pdf
sgnezdov 25:65e430b98cbe 68
sgnezdov 25:65e430b98cbe 69
sgnezdov 26:1798e352679a 70
sgnezdov 22:3af582d8e227 71 */