Create Software Libraries for Ansteron Board


1. How software libraries work

Software libraries are files containing a set of functions that can be added to any program. These functions can then be used just like other functions of the program itself. Software libraries come in files with ".lib" extension. They are added to a program by including them into Additional libraries section of Compiler settings (in Ansteron IDE, go to menu Build then select Compiler settings).

Functions of a library are nothing different than functions of the program. They are actually just a way to re-use the works that had been done across different programs. The process for making a library is the same as making a program. In fact, any program can be turned into a library and all of its function can be recycled, except the "main" function.

When Ansteron IDE compiles a program, it will automatically exclude unused functions to save memory. However, static data (text), global variables and interrupt functions of the library are not excluded even if they won't be used. Therefore, the program should only include the libraries that it will need. Some library may use functions from other libraries as well. In that case, the subsequence libraries must also be included into the program.

2. Create a library

Any program created in Ansteron IDE has two output options. It can be compiled into an executable binary to be downloaded onto Ansteron Board or it can be compiled into a library. When a program is compiled into library, its "main" function is excluded. The library files contains linkable information, compiled binary code, static data (such as text) and preprocessor definitions. Source of the library is not included. To compile a program as library, open Compiler settings dialog then check Generate library option.

Since the main function won't be included in a library, it can be used for debugging the library while being built. A regular program can be turn into a library just by switching the compiler option as mentioned above. However, unused text and global variables should be removed in both cases.

Making a library usually have to deal with low level part of Ansteron Board, such as registers, interrupts,...and reference to CPU datasheet (ATMEGA328P) is recommended. The topics below are available tools for building a library:

Low level access

This is an option in Compiler setting. When low level access is enabled, all registers of the CPU become visible. The library can directly read and write values to those registers to control the operation of corresponding hardware. For example, set and clear pin B5 directly by reading current value of pin register, modify bit 5 then write back:

The same process can be applied to any register. It is important that library should only change the bits that are needed and leave other ones the same. A complete list of registers, their name and functions of each one are described in CPU datasheet.

Interrupts

Interrupts can be used to create a so called "background task" which can run without the attention of main program. The library can utilize interrupts from different peripherals to handle data transfer, protocol or automatic tasks and provide easy to use interface for users. Full description about handling interrupts is described in another article (link).

Buffers and pointers

Data buffers can be created as an array of variables. They can be accessed using an index as well as a pointer pointing to that buffer. These two can be used to handle strings and data transfers. Attention should be made when using pointers since accidently write to memory space that contain registers may cause the CPU to have unexpected behaviors. These errors may not be detected when debugging.

Timing

For the tasks that timing is required, counting instruction cycles can give a very accurate measurement. When a library is being built and compiled as a program for debugging, a file with ".map" extension is generated along with other outputs which contains the list of instructions generated. The file can be viewed with any text editor. Some dummy read or write can be added to adjust the time. See example below:

The output .map file is viewed with WordPad:

System functions

They are functions for controlling special features of the CPU and all of them start with the prefix "system_". Functions such as "system_disable_interrupts();", "system_enable_interrupts();",... are equivalent to CPU instructions CLI, SEI. The library can also provide call back feature with system_indirect_call_function(); or accessing data attachment on program memory with system_read_program_memory();. Description of all system functions can be found in standard library (link).

Preprocessor

Preprocessor provides a simple way to define constants as identifiers. These identifiers can be used as options for a functions or settings instead of giving a number explicitly. Identifiers can be defined in Preprocessor tab or adding a preprocessor script file (.pre) into Additional libraries section of Compiler Setting. All definitions in Preprocessor tab will be carried with the library and the ones from preprocessor script files will not. Preprocessor script files are similar to text files but with ".pre" extension.

Serial Interface for debugging

Serial interface can be very useful when debugging the library. Serial functions from Standard library can be used and then removed when the library is complete. Serial Terminal of Ansteron IDE is simple to use, it will also automatically disconnect when a program is going to download and reconnect by itself. Note that it takes a second for the Serial Terminal to re-establish the connection. Some data may not be captured if Ansteron Board starts sending data immediately after reset.

3. Note

There are some conventions that all libraries should follow to make it compatible with other library as well as less confusing to new users:

  • Standard library will always be there, libraries can always rely on it. It does not have any static data or global variables so it costs nothing to a program to include the library.
  • I/O pins constants (PIN_Bx, PIN_Cx, PIN_Dx) that are defined by standard library can be used for different functions as well as libraries. These constants are 16 bit integers with high byte is the base address of the pin and low byte is the mask. This will take more time and memory than directly access. However, it's fast enough and easier to use. See source file of Standard library for example.
  • All timers should run at maximum clock for all purpose. The reason is to keep PWM outputs at highest quality possible. If interrupts from timers are used and lower rate is needed, a software-based prescaler can be implemented instead of reducing timer clock.