Patent Description:
Microcontrollers are electronic devices integrated on a single chip. Their principle of operation is common to the microprocessors, which are differentiated by the fact of having on board the memory elements and the interface devices required for the digital control specific applications mostly in embedded systems that include sensors and actuators for most varied purposes.

Microcontrollers, as well as microprocessors, need to be programmed, i.e. equipped, internally or on an external memory, with binary language code providing the sequence of instructions that each device must perform during its operation.

In order to set-up the microcontroller functional program it is possible to use low-level programming languages like assembler as well as languages of slightly higher level such as C / C++. Both these programming solutions are closely related and linked to the hardware characteristics of the microcontroller and the board where it is slotted. They are, namely, single-platform programming solutions.

Alternatively, there are systems that allow the usage of high-level languages (e.g. Python) to abstract the specific microcontroller board to be programmed. These system enable a cross-platform structure able to reuse or supplement the developed code on different boards, in the form of scripts to compile and link with additional modules, libraries, as well as low level drivers to build the binary code to be transferred on the program memory.

A very efficient multi-platform system to achieve the above mentioned functionalities is a solution that makes use of a Python <NUM> subset to make highly powerful architectures for embedded systems. <FIG> shows an example of such an architecture. The IDE (Integrated development environment) runs on Windows platform, Linux or Mac. It includes a number of development tools shown at the top of the figure ("Tools and IDE"), in particular an Editor and Bytecode Compiler, which allow to build Python scripts (Programs) and "Modules" for the management of drivers, sensors, actuators present on a board, shown in the figure with the "Hardware" designation, using a generic applications library ("Applications").

For each hardware architecture (Microprocessor + peripherals) a Virtual Machine (VM) is set and copied to the on-board program flash along with the real time operating system (RTOS) and the low-level specific codes for the present microcontroller and peripherals (Hardware Abstraction Layer - HAL).

The real time operating system along with the low-level codes represent the core that interprets Python scripts compiled as bytecodes.

The C language compiled codes are translated into machine instructions immediately readable by the controller without the need to be interpreted by the virtual machine.

The operation that allows to develop the executable code, defined "linking", allows the various modules to be assembled together in order to become a unique code with a very specific memory allocation.

The linking operation is present both in high-level and low level languages, and it represents the final phase of a code development process before it is transferred to the program memory that will be executed by the microcontroller.

This is a highly inefficient process because it must be replicated whenever a single part of the program is modified, entailing a scratch transfer of the entire machine code. Document <CIT> discloses a system for upgrading a non-volatile memory image by partitioning the memory into a plurality of regions that can be directly overwritten without having to overwrite the whole memory. This system, however, still requires linking the modules either statically or dynamically. In the former case, all drivers, also those unused, need always to be loaded in the memory thus leading to a waste of memory. In the latter case, a dynamic code is generated that requires a symbol resolution mechanism at runtime thus leading to a waste of time.

Patent document <CIT>, describing systems and methods for upgrading a non-volatile memory image such as a flash ROM, and articles "<NPL>et Al, and "<NPL>et Al, are also relevant for the background of the invention described herein.

It is thus an object of the present invention to provide a method for high-level programming of microcontroller/microprocessor boards which allows to optimize the lead time needed to transfer the machine language code in the program memory for its execution, memory occupation and runtime speed.

In accordance with embodiments herein, computer implemented methods are provided for the preparation of code to be executed by programmable control devices as defined by independent claim <NUM>.

In practice, the link operation is performed at the time of the upload of the binary code rather than in the previous phase as commonly occurs in the systems according to the prior art. All thanks to the use of an allocation memory that keeps track of the lengths of the code as well as of the beginning and end of each module to be loaded so that the core does not need to be reloaded every time as well as the modules not subject to changes. This is particularly advantageous in case of use of high-level programming languages. The characteristics of the invention and the advantages derived therefrom will appear more clearly from the following detailed description of the accompanying figures.

With reference to <FIG>, the architecture of a system according to an embodiment is now disclosed.

The architecture comprises a set of programming tools <NUM><NUM>, an application program <NUM>, a set of code modules <NUM> acting as a middleware between the application <NUM> and the low level code <NUM> implementing the multithreading mechanisms and the hardware abstraction layer, a hardware <NUM> represented by a board <NUM> with mcu/mpu capabilities installed together with a persistent memory <NUM> and possibly a set of sensors and actuators <NUM>.

The set of programming tools <NUM><NUM> comprises a code editor <NUM><NUM> that enables the writing of programs. Such programs can be written in high level languages (e.g. Python) and optionally in low level languages (e.g. C) and are transformed in two stages: the first stage is performed by the compiler <NUM><NUM> that, given a program, converts it in a non executable low level code consisting of bytecode and optionally assembly code. Such non-executable low level code is then transformed again by the uplinker <NUM><NUM><NUM> in the second stage to obtain the final application code <NUM>. The term uplinker is used in the present disclosure to identify a software/hardware module configured to transfer unlinked code to a program memory.

The set of programming tools is also composed of a mobile app <NUM><NUM> which is able to connect to devices programmed with a specific mobile-enabled application code <NUM> and to display a graphical user interface; moreover the mobile app <NUM><NUM> is able to establish a bidirectional connection with a device and exchange messages with it. The mobile app <NUM><NUM> features a mechanism for the discovery of devices programmed with a mobile-enabled application code.

The set of programming tools is completed by a module for cloud connectivity <NUM><NUM> that saves remotely both the development environment configuration and the programmer project files; and a package manager <NUM><NUM> for managing the extension of the set of programming tools with additional modules and components.

<FIG> illustrates functional components of a code transferring system according to embodiments herein. The code transferring system comprises Hardware <NUM>, Software running on a mcu/mp <NUM>, a Computer system hosting the code transferring toolchain <NUM> and a Communication <NUM> between <NUM> and <NUM>.

The Hardware <NUM> may be composed of a Processor/Controller unit mounted on a Board <NUM> , Sensors and Actuators <NUM> and a ROM Flash Memory <NUM>.

The Software running on a mcu/mpu <NUM> comprises a Virtual Machine <NUM>, a RTOS <NUM>, a Memory Manager <NUM> and a Hardware Abstraction Layer (HAL) <NUM>.

The Computer system hosting the code transferring toolchain <NUM> is composed of an Application code <NUM>, a Compiler <NUM> and an Uplinker <NUM>. The Communication <NUM> represents the interaction between the Computer <NUM> and the Software <NUM> running on Hardware <NUM>.

The Application code <NUM> can be composed of Software Modules <NUM><NUM> written in low level language (e.g. the C language), Modules implementing parts of the HAL <NUM> written in low level language (e.g. the C language) and programs written in High Level Languages <NUM> (e.g. Python).

The Compiler <NUM> takes as input Software Modules <NUM><NUM> and Modules implementing parts of the HAL <NUM> producing Assembly code <NUM>; it also takes as input programs written in High Level Languages <NUM> producing Bytecode <NUM>.

The Virtual Machine <NUM> comprises a System Initialization <NUM><NUM> and a Bytecode Interpreter <NUM> while the RTOS <NUM> comprises a Scheduler <NUM> and Threading Primitives <NUM> (e.g. Mutexes, Semaphores, etc.); The Memory Manager <NUM> organizes RAM in a Heap <NUM> managed by a Garbage Collector <NUM>. The Hardware Abstraction Layer (HAL) <NUM> abstracts the hardware <NUM> When a program is written in a high level language (such as Python or JavaScript) from which C functions are called, the computer interprets the high level language and turns it into bytecode or in a particular dialect that the virtual machine is able to interpret or, with regard to the C functions, they are directly converted into the assembler.

Actually the real time operating system and the core code of the VM occupy a determined memory space (almost constant), while the remaining flash space is gradually filled with the software modules and the hardware modules. When the Python or JavaScript or LUA script is ready and the board is configured, the uplinker statically calculates the size of all modules at compile phase, preparing the table with the start and end position and saves them in the flash while minimizing RAM usage.

The virtual machine is able to run in machine language code, not interpreted, obtained by compiling the intermediate level language (C / C ++) and linked at the time of the upload in a manner comparable to the bytecode. In order to be executed by the virtual machine, the machine language code is subject to the following constraint: the functions that are called and not contained in it belong exclusively to the set of functions exposed by the core code of the VM.

The architecture described in <FIG> is able to retrieve the board vendor ID and other information written permanently in the board of the chip. In this way, the system also allows to assign different names to all the connected boards, which are then recognized through the disambiguation of the IDs. To achieve this behaviour, the system generates a configuration file of board_cfg. xx type that is included in the project and used by the compiler to translate the names of the pins in accordance with the specific ID pin mapping.

<FIG> shows two cases where the uplinker manages the flash memory according to the hardware and software requirements. Different RTOS can require different spaces, while the core system remains almost constant. The size of the System HAL depends on hardware features while the "ad hoc data" may vary. Hardware modules (drivers) and software modules are loaded only if included within the script. The two cases in <FIG> show two different situations that differ in the board, in the "ad hoc data" and in hardware modules (drivers of sensors or shield) and in the used software modules.

The layout of ROM image <NUM> is intended to group both VM code and Application code with all the necessary components within specific regions. The size of each region is dependent upon the code intended to reside within each region.

A region containing VM code <NUM> contains specific segments of code implementing different set of functionalities such as System Initialization segment <NUM><NUM> , Bytecode Interpreter segment <NUM>, RTOS segment <NUM>, HAL segment <NUM> and an optional AdHocData segment <NUM>. A region containing VM code is advantageously partitioned in such a way that the System Initialization segment <NUM><NUM> is the first to be executed.

A region containing Application code may contain specific segments of code and segments of data with a layout computed by the Uplinker <NUM><NUM><NUM>.

System initialization is smartly achieved. When the mcu/mpu is powered, the first code to be executed is the System Initilization <NUM><NUM>. In this phase the microcontroller is configured to optimally execute the bytecode interpreter <NUM>. The configuration parameters are taken from the persistent memory segment called AdHocData <NUM>. Among the configuration data stored in the AdHocData segment there are flags recording the status of the previous System initialization phase (OK or Failed) together with the address to jump to in order to continue execution after the System Initialization phase.

This mechanism allows to have multiple Virtual Machines <NUM>, <NUM> hosted on the same board and to select one of them to be executed according to the AdHocData segment <NUM> parameters.

AdHocData segment parameters can be modified from Application code by calling specific VM function(s) (F0 in <FIG> (symbol table)). Moreover, a failsafe mechanism is included in the System Initialization phase: if the previous run failed for some reason (Fail flag in AdHocData), the control is passed to the last working VM. The ROM occupied by non currently running VMs can be deleted by the running VM and reused for its own purposes, provided that the System Initialization segments of the inactive VMs are left untouched.

A method for transferring code to a non-volatile memory image representing ROM of the device hosting a VM <NUM> involves establishing communication between a software component (Uplinker) running on the computer hosting the toolchain and the VM running on the device.

<FIG> is the uplinker workflow illustrating a process for transferring code to a non-volatile memory according to embodiments herein. The process includes operations <NUM> -<NUM>. The order in which the process is described is not intended to be construed as a limitation. The operations are performed by the interplay of the Uplinker with the VM hosted on the device. Alternatively, the process <NUM> can be implemented in any suitable hardware, software, firmware, or combination thereof.

At <NUM> , the uplinker loads the compiled code consisting of bytecode and (optionally) non-executable assembly code due to unresolved symbols. At <NUM>, the Uplinker establishes communication with the target VM running on a device, by exchanging a message sequence over a transport layer, such sequence realizing a handshake step where compatibility between Uplinker and VM versions is checked. At <NUM>, the VM sends to the Uplinker the Symbol Table (<FIG>) containing the absolute addresses (P0,P1 ,. Pn) in the device ROM of segments of VM code representing the implementation of selected VM functions names (F0,F1 ,. At <NUM>, the VM sends the available ROM size to host the application code and its desired starting position. At <NUM>, the uplinker uses information received at <NUM> to create a single segment, space optimized image holding application code. At <NUM>, the uplinker uses information gathered at <NUM> to resolve missing symbols in the application code, producing an executable code <NUM> statically linked to the particular VM it established communication with. Thanks to operation <NUM>, the produced image is also optimized in terms of code execution time. Indeed, by statically resolving missing symbols at upload time (namely, substituting occurrences of Fn with the corresponding address Pn), the uplinker avoids the need for the VM to have a symbol resolution mechanism at runtime, making function calls for missing symbols as fast as possible (that usually amount to a single assembly instruction jumping to Pn). Without the uplinker, the produced application code would have contained unresolved symbols and the VM would have been forced to implement a mechanism of runtime resolution; for example, by translating the calling of function Fn to first the lookup of the position Pn for Fn in the symbol table and then a jump to Pn, at least doubling the number of instructions for a function call. At <NUM>, the Uplinker sends produced code image to the VM which, at <NUM>, stores the received image in to the ROM starting at the desired position communicated at <NUM>. Finally, at <NUM>, the VM triggers a reboot to transfer execution to the System Initialization that will eventually start a bytecode interpreter to execute the transferred application code.

<FIG> shows two different cases where the uplinker <NUM> organizes the flash memory <NUM> according to two different architecture requirements <NUM>. In <FIG> the architecture requirements are exemplified by a specific Board <NUM> equipped with sensors <NUM> and a software stack comprising secure communication protocols <NUM> (possibly written in a low level language) over a wifi transport layer <NUM> (possibly written in a high level language). In this case the uplinker <NUM> produces an application code <NUM> that is able to use sensors in a hardware independent manner by calling functions of the HAL <NUM>; the application code is able to run in a multithreaded environment in a RTOS independent manner by calling functions residing in the VM <NUM>; such functions hides the implementation of multithreading of that particular RTOS <NUM> to the application code.

In <FIG> a different set of architecture requirements is shown: Board <NUM> equipped with a Buzzer actuator <NUM> and a software stack comprising ethernet transport layer <NUM> (possibly written in a low level language) and a Fast Fourier Transform Algorithm <NUM> (possibly written in a high level language).

As it can be noticed in <FIG>, a different RTOS can be chosen to adapt the VM performance to the architecture requirements.

Flash <NUM> can also be used to load html templates, json files, images, etc. and a method of data exposure related to the sensors and actuators and code in bidirectional mode (from micro to mobile and vice versa). When the object carrying the bytecode generated by the development environment is recognized by a mobile device via wifi, bluetooth, zigbee, etc then the MOBILE APP <NUM> (<FIG>), that is included in the architecture that is located on the mobile device, connects for example in secure mode using SSL / TSL <NUM> with the object and becomes the object interface according to the data display method, the template and the images. The MOBILE APP is generic, i.e. the user will download a version that allows him to make discovery of objects programmed with the architecture described in <FIG> and connect to them. They will expose different interfaces based on the information loaded into the flash memory. This allows a reduction in the development time of the Mobile App. Also the fact that the template, images etc. are located within the object's memory allows an interface between object and APP even without internet connection, and through the use of other types of connection.

Claim 1:
Method for defining a code to be executed by a programmable control device comprising:
having a programming language;
having a code written by using said programming language (<NUM>);
compiling the code by using a machine language to obtain a machine language compiled code, divided into a core code and an application code, said application code being loadable into a program memory independently of the core code;
generating an allocation table comprising the size, start location and end location of each module forming the application code;
transferring said machine language compiled code onto the program memory to be executed by the control device;
linking said core code and said application code during said transferring, on the basis of said allocation table, and of a symbol table communicated by the core code, said symbol table comprising the symbols of the core code and the position of said symbols in the core code.