The Project board is for sharing projects based on Silicon Labs' component with other community members. View Projects Guidelines ›

Projects

    Publish
     
      • Using a script language in EFM32 environment

        Attila Varga | 06/182/2020 | 11:59 AM

        Using a script language in EFM32 environment

        This article describes the usage of a script interpreter in EFM32 environment. The chosen language is the Lua language, the used board is the Silicon Labs Pearl Gecko (SLSTK3402A) starter kit board and the development environment is the standard IDE of Silicon Labs: Simplicity Studio. In the next section a brief description of the script language is provided followed by the goals, requirements and architecture descriptions. You can also find an attached source code and an explanation how to use this example project.

        For the impatient:

         

        • flash the provided .s37 file onto a Pearl Gecko
        • use a terminal emulator (over VCOM) to see the menu (type: help)

        Contents:

          - 1. Brief description of Lua
          - 2. Why do I need a script interpreter?
          - 3. Goals
          - 4. Requirements
          - 5. Architecture
          - 6. Implementation
          - 7. Uploading scripts
          - 8. How to use
          - 9. Future improvements
          - Additional notes:
          - Examples
          - Fazit (conclusion)

        1. Brief description of Lua

        According to the Lua website:
        "Lua is a powerful and fast programming language that is easy to learn and use and to embed into your application."

        The emphasis is here on "embeddable". Lua is a software package designed from start to embed into a so-called "host", which is (in most cases) a foreign, compiled language. Most often it is C, but it can be also any other language. Lua is used in a wide variety  of application, aerospace, photography, research and mostly: in games (due to its speed). It is easy to learn, the hello-world example is a one-liner and the language elements have a low learning threshold.

        An example of Lua code:

        local function run()
          print("--Run--")
          while counter < threshold do
            if IsBtnPushed() then
              if (counter % 8) == 0 then
                print("down")
              end
              Delay(10)
              counter = counter + 1
            else
              counter = 0
            end
          end
        end

        2. Why do I need a script interpreter?

        C is a powerful language, why do I need then an other language?
        What Lua does offer is what C is not good for: dynamic structures, no redundancies, ease of usage, safe environment, automatic memory management and handling strings and other kinds of data with dynamic size.

        Other aspects are that the language is easier to learn by non-programmer thus it gets an environment for a broader user attendance.

        An embeddable script language has the advantage that it can be used as part of the application that is frequently changed without the need of recompilation, for example in handling configuration parameters, automatic test cases, measurements, tryout/oneshot programs, user provided code, customize layout and/or behavior, etc.

        You can give the user the possibility to change something in the application. It is easy to develop and platform independent. But bear in mind that if you provide the possibility to modify something in your application then it must be a safe environment. Fortunately Lua can be configured to have this kind of 'sandbox'.

        3. Goals

        The goal of the project to use a working interpreter embedded in C code. It is not intended to be a complete, full-featured development environment for some kind of application but to provide a firm base to develop one.

        4. Requirements

        The Lua interpreter requires a processor and some amount of random access memory (RAM), it can be satisfied with few resources but - because it is not a stripped down package - it needs some. At startup the Lua interpreter consumes about 17kB of RAM but memory usage depends on the allocation of variables. The interpreter itself needs some memory too and a larger amount of flash for the code itself. Therefore a starter kit with 256kB with RAM and 1MB of flash is used: a Pearl Gecko.

        The starter kit has some hardware, LEDs, buttons, temperature-sensor, LCD display. It provides the possibility to show how a hardware element can be controlled by Lua.

        Also there must be a possibility to upload programs to the starter kit to change its behavior, therefore we need a mechanism to deliver script code (from outside to the kit) that can be executed on the board.

        5. Architecture

        The structure of the project can be seen on the next picture.


        To the main application a Lua interpreter module is linked but it (the main) does not call into it directly. Instead an interface is created where the application can request some services.

        In this project it can require only two things:

        • load a script (from outside)
        • execute the loaded script

        Lua can do a little bit more:

        • control the LEDs (on/off/toggle)
        • read the button states (up/down)
        • read the values from the temperature sensor
        • read and write from/to stdin/stdout (see later)
        • write onto the LCD screen (lines/circles)

        6. Implementation

        Because Simplicity Studio creates makefiles on the fly, it is not difficult to add a Lua interpreter to the project. You have to create a simple example project that fits your needs and add a new folder inside the project directory. Download the Lua source files from the website and copy all the source files into the newly created directory, except `lua.c` and `luac.c` (or exclude both files from the compilation). Both are in the Lua distribution to demonstrate the use of the Lua package. `lua.c` passes the overgiven parameters from the command line to the interpreter; `luac.c` is a Lua 'compiler' (Lua converts the scripts into tokens before executing it). Both has a `main()` function therefore they cannot be added to the project. Don't forget to add the folder to the include directories that other files can include the Lua header files.

        The next step is to create an interface to Lua. This has a predefined protocol. Because Lua is a dynamically typed language, data exchange to the host language occurs over a so-called 'virtual stack'. Lua (or the C code) places values onto that stack and the other language can use it.

        The other thing is to have an interface from Lua to the Gecko SDK (thus to the hardware). This can be done by simply calling functions of the SDK, all the examples and applications do that.

        To have access to the Gecko SDK, Lua has to be extended with C code. C code that is called from Lua must be registered in the interpreter, that means that if the script executes an appropriate statement (e.g. a function call) then the corresponding C code is executed. It communicates (overgives parameters and returns results) over the previously mentioned virtual stack.

        In the example application interface to controlling the LEDs, the LCD display, reading the temperature sensor is implemented. Read and write to the standard input/output files is also implemented (only partly). The Gecko does not have console therefore these read/write operation are redirected to the already present VCOM interface and by connecting a computer to the serial line (with a terminal program) this can be used as a text based interface (for humans and applications).

        Functions that can be called from Lua are as follows:

          print(...)              -- print to console
          LED(0, true)            -- switch LED on/off
          temp, rh = TempRh()     -- measure temperature
          Delay(400)              -- sleep for x miliseconds
          ToggleLED(1)            -- invert LED state
          ClrScr()                -- clear the LCD display
          Line(1,2,3,4)           -- draw a line (on LCD)
          Circle(64,64,40)        -- draw a circle
          LCDrefresh(bool)        -- switch LCD refresh on/off
          bool = IsBtnPushed()    -- read button state (BTN1)
          str  = ReadCon()        -- read a line from terminal
          DrawPixel(x, y)         -- draw a dot on LCD

        To have a console-like user interface the project redirects standard I/O files to a serial line. The SDK has already predefined files for that. Add

        retargetio.c
        retargetserial.c

        to the project files. These pass `printf/getch` type function outputs to the already on the board present VCOM serial line and reads the input from that line. The data will be sent through the USB port to the connected computer. You can use a terminal emulator program (Tera Term, minicom, PuTTY) on your computer to communicate with the board.

        The provided project export (the .sls file) has to be imported (into Simplicity Studio), compiled and flashed onto the Gecko board. The user can use a terminal program to communicate with the application. I use Teraterm because it has the ability to upload files with the XMODEM protocol already implemented. The computer side can be of course a custom application. In that case other type of serial protocol can be used but it have to be implemented on both sides. In that case the file `lfg_xmodem.c` has to be changed/replaced. Baud rate has to be set to the value of 115200.

        lfg_xmodem has a very simple interface, it provides only one function: 
         

        int lfg_XmodemReceive(char *recvBuffer, int recvBufSize, int *actSize);


        It starts the communication and places the received data into the provided text buffer and reports the number of received data into the variable that points `actSize` to. Return value can be LFG_OK or an error code.

        7. Uploading scripts

        There is not much of use of an application when the scripts has to be inserted/compiled into the C code. It loses the flexibility provided by the script language. Therefore the example project uses the XMODEM protocol to copy scripts from a computer to the Gecko board over the serial line. Fortunately there is already a serial line present called VCOM. If you plug in your board via the USB connector it does three things. Implements a JTAG interface, creates an USB mass storage device, realizes a serial communication interface. The latter is used to upload scripts to the board. COM port number can be determined by the Device manager or by the /dev/ttyUSBx file (in Linux).

        XMODEM is a simple file transfer protocol, it allows users to transmit files between computers when both sides use the same protocol. The next picture shows the program structure to receive data:

        8. How to use

        By pressing the reset button on the Gecko board the following lines are displayed on the terminal:

        Lua for Gecko - example application
        memory used :   11.18164 kB
        
        Enter command (or help).
        >
        

        Enter 'help' to display the available commands.

          led 0 on        switch led 0 on
          led 0 off       switch led 0 off
          led 1 on        switch led 1 on
          led 1 off       switch led 1 off
          temp            measure temperature
          clrscr          clear the LCD display
          cls             clear the console
          ---------       ---------------------
          load            load script (from PC) with xmodem protocol
          cat             display loaded script
          dump            display loaded script as hex
          forget          clear loaded script
          run             run loaded script
          help            display help

        Most of them are fairly straightforward, one thing has to be explained: the script upload.

        The XMODEM protocol requires that the receiver (the Gecko board) starts the communication, but the sender (the terminal program) has to be already in 'send' mode and waiting (for the start signal) to start sending. Therefore the first thing is to put the Gecko board into send mode by entering the `load` command. This does not start the communication but waits for an event to start. The Tera Term program must be instructed to send a file (File -> Transfer -> xmodem -> Send... menu item). It will wait for a start signal from the receiver. The start signal can be issued by pressing the `BTN0` button on the Gecko board. Press BTN0.

        That loads a script onto the board. There are already some example scripts that the user can upload (e.g. example1.lua ...). This uploads but does not start the script automatically. To run the script the `run` command has to be entered. Type 'run'.

        a.) enter 'load' on the terminal (Tera Term)
        b.) use send-file in Tera Term
        c.) press 'BTN0' on the Gecko board
        d.) type 'run' into the terminal

        9. Future improvements

        If all went well you have a working environment where you can evaluate Lua running on a Gecko board. But there is a lot of space for improvement.

        • Persistence
          • Scripts should be stored in a persistent storage that they can live also after reset. There is only one such kind of storage: the flash. For that the so-called 'user page' or the 'NVM3' can be used. On a Giant Gecko an SD card can be used.
        • Debug
          • More complex script have also more complex behavior. Sometimes it needs to be evaluated by a step-by-step execution.
        • Radio
          • A good improvement would be to deliver scripts over the air by using a radio board.

        Additional notes:

        • the used XMODEM implementation is not for a production scale application. It has no timeout, no error recovery. Only receive is implemented. It has been only used for the task to deliver code to the board.
        • in the file `luaconf.h` the #define LUA_32BITS is activated to use 32 bit integers.

        Examples

        There are already some examples in the `src` folder:

        • example1.lua:
          •   demonstrates the use of LEDs, measuring temperature and drawing lines on the LCD screen
        • example2.lua:
          •   reads the BTN1 button state and reports it to the terminal
        • example3.lua:
          •   reads a line from the console
        • example4.lua:
          •   displays graphic on the LCD screen

        Fazit (conclusion)

        "Lua is becoming the language of choice for anyone who needs a scripting language that is simple, efficient, extensible, portable, and free. Currently, Lua is being used in areas ranging from embedded systems to Web development and is widely spread in the game industry, where knowledge of Lua is an indisputable asset." (Google.books)

        Lua has a lot of sophisticated additional things under the hood (tables, metatables, threads, user defined types ...), this article scratches only the surface of the possibilities that can be reached by using a powerful script language.

        Thank you.