This document describes how to to port the server to a specific board.
All data is stored in base_t
type.
This define is equal to the maximum length of the string representation of a base_t
.
All data is addressed through the addr_t
type.
This define is equal to the maximum length of the string representation of a addr_t
.
This define is equal to the count of the buffers with witch the data will be transmitted
via the mem functions. In other words every mem_read\write call will read\write MAX_MEM_BUF_LEN
base_t
units or less.
A specific port should define a lowlevel_api
structure, assigning it's
fileds appropriate functions.
typedef void (*write_register_t) (address_t addr, base_t value);
typedef void (*read_register_t) (address_t addr, base_t *value);
typedef void (*write_memory_t) (address_t addr, base_t *value, size_t len);
typedef void (*read_memory_t) (address_t addr, base_t *value, size_t len);
typedef int (*take_func_t) (void);
typedef void (*release_func_t) (void);
typedef int (*open_func_t) (void);
typedef void (*close_func_t) (void);
struct lowlevel_api {
take_func_t take;
release_func_t release;
write_register_t reg_write;
read_register_t reg_read;
write_memory_t mem_write;
read_memory_t mem_read;
ssize_t (*base_to_string)(base_t num, char string[MAX_STR_BASE_T + 1]);
int (*string_to_base)(char string[MAX_STR_BASE_T + 1], base_t *num);
int (*string_to_addr)(char saddr[MAX_STR_ADDR_T + 1], address_t *addr);
char *name;
};
void (*write_register_t) (address_t addr, base_t value);
void (*read_register_t) (address_t addr, base_t *value);
void (*write_memory_t) (address_t addr, base_t *value, size_t len);
void (*read_memory_t) (address_t addr, base_t *value, size_t len);
The server already have some default functions to convert strings to numbers and etc, but in case of an unusual type the following functions could be also specified.
ssize_t (*base_to_string)(base_t num, char string[MAX_STR_BASE_T + 1])
base_t
type to a string,
the resulting string length is returned. Upon error a -1 return value is expected.int (*string_to_base)(char string[MAX_STR_BASE_T + 1], base_t *num)
base_t
.
Upon error a -1 return value is expected, upon successful execution a return value of 0 is expected.int (*string_to_addr)(char saddr[MAX_STR_ADDR_T + 1], address_t *addr)
addr_t
.
Upon error a -1 return value is expected, upon successful execution a return value of 0 is expected.int (*open_func_t) (void);
int (*take_func_t) (void);
void (*close_func_t) (void);
void (*release_func_t) (void);
struct lowlevel_api dummy_api = {
.reg_write = dummy_write_register,
.reg_read = dummy_read_register,
.mem_write = dummy_write_memory,
.mem_read = dummy_read_memory,
.name = "dummy api"
};
struct lowlevel_api *API = &dummy_api;
API
pointer to the needed "low level api" structure.The api's are exported through the API
object so setting it to a valid pointer it's a must.