-
Notifications
You must be signed in to change notification settings - Fork 17
Porting picoTCP HW
PicoTCP can run on several different hardware architectures and can be integrated with virtually any operating system or within a standalone application. It is possible to run PicoTCP on big-endian as well as little-endian CPU configurations. PicoTCP uses gcc-specific tags that may not be compatible with other compilers. The amount of resources needed may vary depending on the modules that are compiled-in. However, adapting to a specific hardware platform or for a particular use may require some integration effort.
ensure that the license of your Board Support Package (BSP) is compatible with the license of PicoTCP you are using before distributing any derivative works.
PicoTCP relies on a simple set of system-specific calls that must be implemented externally from the target. Briefly, the interface needed for the stack to run is composed by:
- A mechanism to allocate memory dynamically on the target (malloc/free)
- A stable, monotonic time source variable, in milliseconds, to update internal timers
For the memory allocation interface, two symbols have to be defined by the system:
-
void *pico_zalloc(uint32_t size)
- memory allocator that allocates an object of the givensize
and set its content to 0 -
void pico_free(void *ptr)
- memory deallocator
For the time keeping, the following objects must be defined by the system:
-
static inline unsigned long PICO_TIME(void)
- Returns current time expressed in seconds -
static inline unsigned long PICO_TIME_MS(void)
- Returns current time expressed in milliseconds -
static inline void PICO_IDLE(void)
- Sleep between two consecutive iterations inside the main protocol loop (e.g. to yield the CPU to some other functionality on the system, waiting for IRQs, etc.)
Finally, whenever debug information is needed, the system will have to provide a
dbg()
function that accepts the same variadic arguments model as a standard printf()
. This way the debugging output of the stack can be redirected elsewhere (e.g. UART or file).
If all the above requirements are satisfied, PicoTCP expects those functions to be mapped to
existing code in the BSP of the architecture. An easy way to do so is by means of a new
architecture-specific header file under the
include/arch
subdirectory. Since all the functions
above must already be implemented outside the PicoTCP tree, the library will have to be linked
to the system support library, either during compilation or at at a subsequent stage when the
resulting firmware is being generated. For this reason, a prototype of all the functions used
to implement the functionality requested by the BSP must be included from the architecture
support header file or incorporated into the file itself.
For instance, if the BSP for an architecture called "foobar" and provides the following functions:
void *custom_allocate_and_zero(int size);
void custom_free(void *mem);
int print_serial_debug(...);
and an interrupt handler is attached to a time source in order to increment the
pico_ms_tick
variable every millisecond, a possible architecture-specific file (arch/pico_foobar.h) should
look like the following:
/* declare the prototypes used as extern symbols */
extern void *custom_allocate_and_zero(int size);
extern void *custom_free(void *mem);
extern int print_serial_debug(...);
#define dbg print_serial_debug
#define pico_zalloc(x) custom_allocate_and_zero(x)
#define pico_free(x) custom_free(x)
static inline unsigned long PICO_TIME(void)
{
return pico_ms_tick / 1000;
}
static inline unsigned long PICO_TIME_MS(void)
{
return pico_ms_tick;
}
static inline void PICO_IDLE(void)
{
unsigned long tick_now = pico_tick;
while(tick_now == pico_tick);
}
Once the architecture-specific file is created, it is possible to add the architecture-specific support to the pico config.h file, the same way it is done for the existing architectures, using an additional preprocessor elif block:
/* ... */
#elif defined FOOBAR
#include "arch/pico_foobar.h"
/* ... */
From this point on, it is sufficient to define a preprocessor variable with the keyword chosen
for the architecture, all in capitals (
FOOBAR
in this example case). The final step is to create a
block in the main PicoTCP makefile that also sets the compiler
ags needed to produce objects
that are compatible with and/or optimized for the foobar architecture. Additionally, this block
also contains the definition of the keyword preprocessor macro in order to have the correct
arch-specific header included:
ifeq ($(ARCH),foobar)
CFLAGS+=-mcustom-foobar-code -DFOOBAR
endif
To compile for the foobar architecture, it is now sufficient to run
make ARCH=foobar
Getting Started
- Setting up the environment
- Testing
- Configuring and compiling
- Running picoTCP on Linux - Deprecated (see setting up)
- Running picoTCP on Windows
Porting
- Build process explained
- Porting the build to another compiler or IDE
- Porting picoTCP to your favorite embedded target
- Porting picoTCP to your favorite Operating System
- Example device driver
Development