mirror of
https://github.com/elua/elua.git
synced 2025-01-25 01:02:54 +08:00
17487f9ebe
- This should actually be a merge but we made a mistake on the initial repo creation and a merge was not possible. - Below there is a resumed log of the commit messages for the few steps, just for the record. - The merged commit messages for this work are: - Removing Portuguese doc content - Ignore folder names fixed on .gitignore - Removed doc files which content migrated to the CMS - docdata.lua updated accordingly - Doc build checked ok - Overall doc structure and contents still being refined - Removing folder cache from git versioning - Removing folder dist from git versioning. The folders above are generated by the buildall.lua script and are not part of the sources - Adding .gitignore file with objects info to inform git what to ignore - Removed file - Merge branch 'master' of git@repos.giga.puc-rio.br:elua-doc.git - Moving all files and folders to a working doc folder - Css updated - Index page added and CSS adjusts - Merge branch 'master' of git@repos.giga.puc-rio.br:elua-doc.git - Signed-off-by: Guilherme Sanchez <guilhermesanchezpacheco@gmail.com> - Merge branch 'master' of git@repos.giga.puc-rio.br:elua-doc.git - files deleted - Changed function that creates functions submenus. - Menu inserted with árvore, CSS adjusts, google search - Changed past design to new design - CSS updated - initial import - The commit ids were also preserved but they are related to this "other" work done on Led Lab. We'll keep the repo just in case. 4dce3f77c47b0c3001a2075a946e80ee52759b49 - Removing Portuguese doc content 78d8847525cacf045fe7e672cff6bd1e058a6a4b Ignore folder names fixed on .gitignore 48dee6b7962168ab1098bf709ead6f3cfe6b7964 - Removed doc files which content migrated to the CMS - docdata.lua updated accordingly - Doc build checked ok - Overall doc structure and contents still being refined 2aa2fe0c554db03dbc7029c34d0f4500fe625b37 - Removing folder cache from git versioning - Removing folder dist from git versioning The folders above are generated by the buildall.lua script and are not part of the sources - Adding .gitignore file with objects info to inform git what to ignore af6cc2890edf1855af319dc999a03feee5f9bee0 Removed file 6a180e72eb4f4860620cafc0685000e9f2174cfe Merge branch 'master' of git@repos.giga.puc-rio.br:elua-doc.git eb430112e78ae537459ab315e228ebca84bdf2d4 Moving all files and folders to a working doc folder d28a7c99489915630bd2625f3756fecf0d08ce37 Css updated 32836ffe382f04ab07c3e6f018c7b449a20d7a8d Index page added and CSS adjusts 1461d9957d9d25a1467cb57ab8717aa213a37e8d Merge branch 'master' of git@repos.giga.puc-rio.br:elua-doc.git ae1934c04f35a29e25bb4495ae8a31cd9c000b5b Signed-off-by: Guilherme Sanchez <guilhermesanchezpacheco@gmail.com> b5f31d70f1fac8d3fba325c9867a03f976775698 Merge branch 'master' of git@repos.giga.puc-rio.br:elua-doc.git ec9ad8446b7ea38b252c6a416e70774349835e45 files deleted bd7a80151b2030720ba8d8a303467d8c25a4b4b2 Changed function that creates functions submenus. 6a7494acaec694fadbb13520bcbccc51a6b95dfe Inserido menu com árvore, ajustes no CSS, busca do google e979f1c259d425c9a3be83f9cda20eddffe073bb Changed past design to new design. 381459e95286886b052103a0253e60b29e064d7a CSS updated 4f81d2f1195efe733fe5f97517be325d75937bc3 initial import
210 lines
18 KiB
HTML
210 lines
18 KiB
HTML
$$HEADER$$
|
|
<a name="structure" /><h3>eLua architecture overview</h3>
|
|
<p>The overall logical structure of <b>eLua</b> is shown in the image below:</p>
|
|
<p style="text-align: center; valign:middle;"><img src="images/elua_arch.png" style="border: 0;" alt="eLua architecture"></img></p>
|
|
<p><b>eLua</b> uses the notion of <b>platform</b> to denote a group of <b>CPUs</b> that share the same core structure, although their specific silicon
|
|
implementation might differ in terms of integrated peripherals, internal memory and other such attributes. An <b>eLua</b> port implements one or
|
|
more CPUs from a given platform. For example, the <b>lm3s port</b> of <b>eLua</b> runs on LM3S8962, LM3S6965 and LM3S6918 CPUs, all of them part of the
|
|
<b>lm3s</b> platform. Refer to <a href="status.html">the status page</a> for a full list of platforms and CPUs on which <b>eLua</b> runs.</p>
|
|
<p>As can be seen from this image, <b>eLua</b> tries to be as portable as possible between different platforms by using a few simple design
|
|
rules:</p>
|
|
<ul>
|
|
<li>all code that is platform-independent is <b>common code</b> and it should be written in ANSI C as much as possible, this makes it highly portable
|
|
among different architectures and compilers, just like Lua itself. </li>
|
|
<li>all the code that can't possibly be generic (mostly peripheral and CPU specific code) must still be made as portable as possible by using a common
|
|
interface that must be implemented by all platforms on which <b>eLua</b> runs. This interface is called <b>platform interface</b> and is discussed in
|
|
detail <a href="arch_platform.html">here</a> (but please see also <a href="arch_overview.html#platform">"The platform interface"</a>
|
|
paragraph in this document).</li>
|
|
<li>all platforms (and their peripherals) are not created equal and vary greatly in capabilities. As already mentioned, the platform interface tries
|
|
to group only common attributes of different platforms. If one needs to access the specific functionality on a given platform (like the loopback support
|
|
mentioned before) it can do so by using a <b>platform module</b>. These are of course platform specific, and their goal is to fill the gap between the
|
|
platform interface and the full set of features provided by a platform.</li>
|
|
</ul>
|
|
<a name="common" /><h3>Common (generic) code</h3>
|
|
<p>The following gives an incomplete set of items that can be classified as <b>common code</b>:</p>
|
|
<ul>
|
|
<li>the Lua code itself (obviously) plus the <a href="arch_ltr.html">LTR patch</a>.</li>
|
|
<li>all the <b>components</b> in <b>eLua</b> (like the ROM file system, the XMODEM receive code, the <b>eLua</b> shell, the TCP/IP stack and others).
|
|
</li>
|
|
<li>all the <b>generic modules</b>, which are Lua modules used to expose the functionality of the platform to Lua.</li>
|
|
<li>generic <b>peripheral support code</b>, like the ADC support code (<i>src/common/elua_adc.c</i>) that is <b>independent</b> of the actual ADC
|
|
hardware.</li>
|
|
<li>libc code (for example allocators and Newlib stubs).</li>
|
|
</ul>
|
|
<p>This should give you a pretty good idea about what "common code" means in this context. Note that the generic code layer should be as "greedy" as
|
|
possible; that is, it should absorb as much common code as possible. For example:</p>
|
|
<ul>
|
|
<li>if you want to add a new file system to <b>eLua</b>, this should definitely be generic code. It's likely that this kind of code will have
|
|
dependencies related to the physical medium on which this file system resides. If you're lucky, you can solve these dependencies using only the functions
|
|
defined in the <a href="arch_platform.html">platform interface</a> (this would make sense if you're using a SD card controlled over SPI, since the
|
|
platform interface already has a SPI layer). If not, you should group the platform specific functions in a separate interface that will be implemented by
|
|
all platform that want to use your new file system. This gives the code maximum portability.</li>
|
|
<li>if you want to add a driver for a specific ADC chip that works over SPI, the same observations apply: write it as common code as much as you can,
|
|
and use the <a href="arch_platform.html">platform interface</a> for the specific SPI functions you need.</li>
|
|
</ul>
|
|
<p>When designing and implementing a new component, keep in mind other <b>eLua</b> design goal: <b>flexibility</b>. The user should be able to
|
|
select which components are part of its <b>eLua</b> binary image (as described <a href="building.html">here</a>), and the implementation should take
|
|
this into consideration. The same thing holds for the generic modules: the user must have a way to choose the set of modules he needs.</p>
|
|
<p>For maximum portability, make your code work in a variety of scenarios if possible (and if that makes sense from a practical point of view).
|
|
Take for example the code for stdio/stdout/stderr handling (<i>src/newlib/genstd.c</i>): it acknowledges the fact that a terminal can be implemented
|
|
over a large variety of physical transports (RS-232 for PC, SPI for a separate LCD/keyboard board, a radio link and so on) so it uses pointers for its
|
|
send/receive functions (see <a href="arch_con_term.html">this link</a> for more details). The impact on speed and resource consumption is minimum, but
|
|
it matters a lot in the portability department.</p>
|
|
<a name="platform" /><h3>Platform interface</h3>
|
|
<p>Used properly, the platform interface allows writing extremely portable code over a large variety of different platforms, both from C and from Lua.
|
|
An important property of the platform interface is that it tries to group only <b>common</b> attributes of different platforms (as much as possible).
|
|
For example, if a platform supported by <b>eLua</b> has an UART that can work in loopback mode, but the others don't, loopback support won't be included
|
|
in the platform interface.</p>
|
|
<p>A special emphasis on the platform interface usage: remember to use it not only for Lua, but also for C. The platform interface is mainly used by the
|
|
generic modules to allow Lua code to access platform peripherals, but this isn't its only use. It can (and it should) also be used by C code that wants
|
|
to implement a generic module and neeeds access to peripherals. An example was given in the previous section: implementing a new file system.</p>
|
|
<p>The platform interface definition is always in the <i>inc/platform.h</i> header file. For a full description of its functions, check
|
|
<a href="arch_platform.html">the platform interface documentation.</a></p>
|
|
<a name="platforms" /><h3>Platforms and ports</h3>
|
|
<p>All the platforms that run <b>eLua</b> (and that implement the platform interface) are implemened in this conceptual layer. A <b>port</b> is a full
|
|
<b>eLua</b> implementation on a given platform. The two terms can generally be used interchangeably.</p>
|
|
<p>A port can (and generally will) contain specific peripheral drivers, many times taken directly from the platform's CPU support
|
|
package. These drivers are used to implement the platform interface. Note that:</p>
|
|
<ul>
|
|
<li>a port isn't required to implement <b>all</b> the platform interface functions, just the ones it needs. As explained
|
|
<a href="building.html">here</a>, the user must have full control over what's getting built into this <b>eLua</b> image. If you don't need the SPI
|
|
module, for example, you don't need to implement its platform interface.</li>
|
|
<li>a part of the platform interface is implemented (at least partially) in a file that is common for all the platforms (<i>src/common.c</i>). It
|
|
eases the implementation of some modules (such as the timer module) and also implements common features that are tied to the platform interface,
|
|
but have a common behaviour on all platforms (for example virtual timers, see <a href="arch_platform_timers.html#virtual_timers">here</a> for details). You probably won't need to modify
|
|
if you're writing platform specific code, but it's best to keep in mind what it does.</li>
|
|
</ul>
|
|
<p>A platform implementation might also contain one or more <b>platform dependent modules</b>. As already exaplained, their purpose is to allow Lua
|
|
to use the full potential of the platform peripherals, not only the functionality covered by the platform interface, as well as functionality that
|
|
is so specific to the platform that it's not even covered by the platform interface. By convention, all the platform dependent modules should be
|
|
grouped inside a single module that has the same name as the platform itself. If the platform dependent module augments the functionality of a
|
|
module already found in the platform interface, it should have the same name, otherwise it should be given a different, but meaningful name. For example:</p>
|
|
<ul>
|
|
<li>if implementing new functionality on the UART module of the LM3S platform, the corresponding module should be called <b>lm3s.uart</b>.</li>
|
|
<li>if implementing a peripheral driver that for some reason should be specific to the platform on the LPC2888 platform, for example its dual audio
|
|
DAC, give it a meaningful name, for example <b>lpc288x.audiodac</b>.</li>
|
|
</ul>
|
|
<h2>Structure of a port</h2>
|
|
<p>All the code for platform <i>name</i> (including peripheral drivers) must reside in a directory called <i>src/platform/<name></i> (for example
|
|
<i>src/platform/lm3s</i> for the <i>lm3s</i> platform). Each such platform-specific subdirectory must contain at least these files:</p>
|
|
<ul>
|
|
<li><b>type.h</b>: this defines the "specific data types", which are integer types with a specific size (see <a href="arch_coding.html">coding style</a>
|
|
for details. An example from the <b>i386</b> platform:
|
|
<pre><code>typedef unsigned char u8;
|
|
typedef signed char s8;
|
|
typedef unsigned short u16;
|
|
typedef signed short s16;
|
|
typedef unsigned long u32;
|
|
typedef signed long s32;
|
|
typedef unsigned long long u64;
|
|
typedef signed long long s64;</code></pre>
|
|
</li>
|
|
<li><b>conf.py</b>: this is the platform specific build configuration file, used by the <a href="building.html">build system</a> for a number of purposes:
|
|
<ul>
|
|
<li>to get the list of platform-specific files that will be compiled in the <b>eLua</b> image. They are exported in the <i>specific_files</i> string,
|
|
separated by spaces, and must be prepended with the relative path to the platform subdirectory. An example from the <b>i386</b> platform:
|
|
<pre><code>specific_files = "boot.s common.c descriptor_tables.c gdt.s interrupt.s isr.c kb.c monitor.c timer.c platform.c"
|
|
# Prepend with path
|
|
specific_files = " ".join( [ "src/platform/%s/%s" % ( platform, f ) for f in specific_files.split() ] )</code></pre>
|
|
</li>
|
|
<li>to get the full command lines of the different toolchain utilities (linker, assembler, compiler) used to compile <b>eLua</b>. They must be declared
|
|
inside the <i>tools</i> variable, in a separate dictinoary which key is the same as the platform name, and with specific names for each tool in turn:
|
|
<b>cccom</b> for the compiler, <b>linkcom</b> for the linker and <b>ascom</b> for the assembler.
|
|
For example, this is how the <i>tools</i> variable is defined for the <b>i386</b> platform:
|
|
<pre><code># Toolset data
|
|
tools[ 'i386' ] = {}
|
|
tools[ 'i386' ][ 'cccom' ] = "%s %s %s -march=i386 -mfpmath=387 -m32 -ffunction-sections -fdata-sections -fno-builtin -fno-stack-protector %s -Wall -c $SOURCE -o $TARGET" % ( toolset[ 'compile' ], opt, local_include, cdefs )
|
|
tools[ 'i386' ][ 'linkcom' ] = "%s -nostartfiles -nostdlib -march=i386 -mfpmath=387 -m32 -T %s -Wl,--gc-sections -Wl,-e,start -Wl,--allow-multiple-definition -o $TARGET $SOURCES -lc -lgcc -lm %s" % ( toolset[ 'compile' ], ldscript, local_libs )
|
|
tools[ 'i386' ][ 'ascom' ] = "%s -felf $SOURCE" % toolset[ 'asm' ]</code></pre>
|
|
Note how the definition of <b>tools</b> uses the definition of <b>toolset</b>, a dictionary with the names of the tools in the current toolchain. This
|
|
is also part of the <b>eLua</b> build system and is documented <a href="toolchains.html">here</a>.</li>
|
|
<li>to get the name of a <b>programmning function</b> which receives the name of the <b>eLua</b> executable file (the result of the build step) and
|
|
produces a file suitable for programming on the corresponding hardware platform. The name of this function should also be set in the <i>tools</i>
|
|
dictionary, as shown below (example taken from the <b>str7</b> platform):
|
|
<pre><code># Programming function for STR7
|
|
def progfunc_str7( target, source, env ):
|
|
outname = output + ".elf"
|
|
os.system( "%s %s" % ( toolset[ 'size' ], outname ) )
|
|
print "Generating binary image..."
|
|
os.system( "%s -O binary %s %s.bin" % ( toolset[ 'bin' ], outname, output ) )
|
|
|
|
tools[ 'str7' ][ 'progfunc' ] = progfunc_str7</code></pre>
|
|
Note, once again, how this function uses the same <i>toolset</i> variable mentioned in the previous paragraph.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><b>stacks.h</b>: by convention, the stack(s) size(s) used in the system are declared in this file. An example taken from the <b>at91sam7x</b> platform is given below:
|
|
<pre><code>#define STACK_SIZE_USR 2048
|
|
#define STACK_SIZE_IRQ 64
|
|
#define STACK_SIZE_TOTAL ( STACK_SIZE_USR + STACK_SIZE_IRQ )</code></pre></li>
|
|
<li><b>platform.c</b>: by convention, the <a href="arch_platform.html">platform interface</a> is implemented in this file. It also contains the platform-specific
|
|
initialization function (<i>platform_init</i>, see the description of the <a href="arch_overview.html#boot">eLua boot process</a> for details).</li>
|
|
<li><b>platform_conf.h</b>: this is the platform configuration file, used to give information about both the platform itself and the build configuration for the
|
|
platform. This is what you can set inside <b>platform_conf.h</b>:
|
|
<ul>
|
|
<li>the list of <b>components</b> that will be part of the build (see <a href="building.html">building eLua</a> for details).</li>
|
|
<li>the list of <b>modules</b> that will be part of the build (see <a href="building.html">building eLua</a> and <a href="arch_ltr.html#config">LTR configuration</a>
|
|
for details.</li>
|
|
<li>the <b>static configuration data</b> (see <a href="building.html">building eLua</a> for details).</li>
|
|
<li>the <b>number of peripherals</b> on your CPU. See an example below (taken from <b>lm3s</b>) that also shows how to differentiate between different CPUs that belong to the same
|
|
platform; the <b>FORxxxx</b> macros are defined in <b>conf.py</b>):
|
|
<pre><code>// Number of resources (0 if not available/not implemented)
|
|
#define NUM_PIO 7
|
|
#define NUM_SPI 1
|
|
#ifdef FORLM3S6965
|
|
#define NUM_UART 3
|
|
#else
|
|
#define NUM_UART 2
|
|
#endif
|
|
#define NUM_TIMER 4
|
|
#ifndef FORLM3S6918
|
|
#define NUM_PWM 6
|
|
#else
|
|
#define NUM_PWM 0
|
|
#endif
|
|
#define NUM_ADC 4</code></pre></li>
|
|
<li><b>specific peripheral configuration</b>: this includes (but it not limited to) enabling buffering on UART, enabling and setting up virtual timers, setting PIO configuration and so on.
|
|
All these parameters are described in detail in the <a href="arch_platform.html">platform interface section</a>.</li>
|
|
<li><b>memory configuration</b>: describes the regions of free RAM in the system, which will be later used by the standard system allocator (malloc/realloc/free). Two macros
|
|
(<b>MEM_START_ADDRESS</b> and <b>MEM_END_ADDRESS</b>) define two arrays with the beginning and the end of all the free RAM memory in the system. If your board has external RAM memory, you
|
|
should define it here. If not, you can only use the internal memory, and you'll generally need to use the linker-defined symbol <b>end</b> to find out where your free memory starts. Following
|
|
is an example from the <b>ATEVK1100</b> (AVR32) board that has both on-chip and external RAM:
|
|
<pre><code>// Allocator data: define your free memory zones here in two arrays
|
|
// (start address and end address)
|
|
#define MEM_START_ADDRESS { ( void* )end, ( void* )SDRAM }
|
|
#define MEM_END_ADDRESS { ( void* )( 0x10000 - STACK_SIZE_TOTAL - 1 ), ( void* )( SDRAM + SDRAM_SIZE - 1 ) }
|
|
</code></pre>
|
|
</li>
|
|
</ul>
|
|
If you want to take a look at a real life example of a <b>platform_conf.h</b> file, see for example <i>src/platform/lm3s/platform_conf.h</i>.
|
|
</li>
|
|
<li><b>networking configuration</b>: if you need TCP/IP on your board, you need to add networking support to <b>eLua</b> (see <a href="building.html">
|
|
building</a> for a list of configuration options related to TCP/IP). You also need to have another file, called <b>uip-conf.h</b> that configures uIP
|
|
(the TCP/IP stack in <b>eLua</b>) for your specific architecture. See <a href="arch_tcpip.html">TCP/IP in eLua</a> for details.</li>
|
|
</ul>
|
|
<p>Besides the required files, the most common scenario is to include other platform specific files in your port:</p>
|
|
<ul>
|
|
<li><b>a "startup sequence"</b>, generally written in assembler, that does very low level
|
|
intialization, sets the stack pointer, zeroes the BSS section, copies ROM to
|
|
RAM for the DATA section, and then jumps to main.</li>
|
|
<li>a <b>linker command file</b>.</li>
|
|
<li>the <b>CPU support package</b> generally comes from the CPU manufacturer, and includes code
|
|
for accessing peripherals, configuring the core, setting up interrupts and so on.</li>
|
|
</ul>
|
|
<a name="boot" /><h3>eLua boot process</h3>
|
|
<p>This is what happens when you power up your <b>eLua</b> board:</p>
|
|
<ol>
|
|
<li>the platform initialization code is executed. This is the code that does very low level platform setup (if needed), copies ROM to RAM, zeroes out
|
|
the BSS section, sets up the stack pointer and jumps to <b>main</b>.</li>
|
|
<li>the first thing <b>main</b> does is call the platform specific initialization function (<b>platform_init</b>). <b>platform_init</b> must fully
|
|
initialize the platform and return a result to main, that can be either <b>PLATFORM_OK</b> if the initialization succeeded or <b>PLATFORM_ERR</b>
|
|
otherwise. If <b>PLATFORM_ERR</b> is returned, <b>main</b> blocks immediately in an infinite loop.</li>
|
|
<li><b>main</b> then initializes the rest of the system: the ROM file system, XMODEM, and term.</li>
|
|
<li>if <b>/rom/autorun.lua</b> (which is a file called <b>autorun.lua</b> in the <a href="arch_romfs.html">ROM file system</a>) is found, it is
|
|
executed. If it returns after execution, or if it isn't found, the boot process continues with the next step.</li>
|
|
<li>if boot is set to 'standard' and the <a href="using.html#shell">shell</a> was compiled in the image, it is started, in the absence of the shell, a standard Lua interpreter is started.</li>
|
|
<li>if boot is set to 'luarpc' an rpc server is started.</li>
|
|
</ol>
|
|
$$FOOTER$$
|
|
|