Commit a371d6f9 authored by Alessandro Rubini's avatar Alessandro Rubini

on-switch-tests: copied libs from ptp-noposix (d55da43)

parent 37e561fa
/*
* This is included by the Makefile before everything else
*/
#ifndef SO_TIMESTAMPING
# define SO_TIMESTAMPING 37
# define SCM_TIMESTAMPING SO_TIMESTAMPING
#endif
#include <stdio.h>
#include <stdlib.h>
#include "hal_exports.h"
#include <wr_ipc.h>
static wripc_handle_t hal_cli;
int halexp_check_running()
{
//int res_int;
//return wripc_call(hal_ipc, "halexp_check_running", ;
return 0;
}
int halexp_reset_port(const char *port_name)
{
// TRACE(TRACE_INFO, "resetting port %s\n", port_name);
return 0;
}
int halexp_calibration_cmd(const char *port_name, int command, int on_off)
{
int rval;
wripc_call(hal_cli, "halexp_calibration_cmd", &rval,3, A_STRING(port_name), A_INT32(command), A_INT32(on_off));
return rval;
}
int halexp_lock_cmd(const char *port_name, int command, int priority)
{
int rval;
wripc_call(hal_cli, "halexp_lock_cmd", &rval, 3, A_STRING(port_name), A_INT32(command), A_INT32(priority));
return rval;
}
int halexp_query_ports(hexp_port_list_t *list)
{
wripc_call(hal_cli, "halexp_query_ports", list, 0);
return 0;
}
int halexp_get_port_state(hexp_port_state_t *state, const char *port_name)
{
wripc_call(hal_cli, "halexp_get_port_state", state, 1, A_STRING(port_name));
return 0;
}
int halexp_pps_cmd(int cmd, hexp_pps_params_t *params)
{
int rval;
wripc_call(hal_cli, "halexp_pps_cmd", &rval, 2, A_INT32(cmd), A_STRUCT(*params));
return rval;
}
#if 0
int halexp_pll_cmd(int cmd, hexp_pll_cmd_t *params)
{
int rval;
wripc_call(hal_cli, "halexp_pll_cmd", &rval, 2, A_INT32(cmd), A_STRUCT(*params));
return rval;
}
#endif
int halexp_client_init()
{
hal_cli = wripc_connect(WRSW_HAL_SERVER_ADDR);
if(hal_cli < 0)
return -1;
else
return 0;
}
#ifndef __HAL_CLIENT_H
#define __HAL_CLIENT_H
#include "hal_exports.h"
int halexp_client_init();
#endif
This diff is collapsed.
This diff is collapsed.
// Network API for WR-PTPd
#ifndef __PTPD_NETIF_H
#define __PTPD_NETIF_H
#include <stdio.h>
//#include <inttypes.h>
#define PTPD_SOCK_RAW_ETHERNET 1
#define PTPD_SOCK_UDP 2
#define PTPD_FLAGS_MULTICAST 0x1
// error codes (to be extended)
#define PTPD_NETIF_READY 1
#define PTPD_NETIF_OK 0
#define PTPD_NETIF_ERROR -1
#define PTPD_NETIF_NOT_READY -2
#define PTPD_NETIF_NOT_FOUND -3
// GCC-specific
#define PACKED __attribute__((packed))
#define PHYS_PORT_ANY (0xffff)
#define PTPD_NETIF_TX 1
#define PTPD_NETIF_RX 2
#define IFACE_NAME_LEN 16
// Some system-independent definitions
typedef uint8_t mac_addr_t[6];
typedef uint32_t ipv4_addr_t;
// WhiteRabbit socket - it's void pointer as the real socket structure is private and probably platform-specific.
typedef void *wr_socket_t;
// Socket address for ptp_netif_ functions
typedef struct {
// Network interface name (eth0, ...)
char if_name[IFACE_NAME_LEN];
// Socket family (RAW ethernet/UDP)
int family;
// MAC address
mac_addr_t mac;
// Destination MASC address, filled by recvfrom() function on interfaces bound to multiple addresses
mac_addr_t mac_dest;
// IP address
ipv4_addr_t ip;
// UDP port
uint16_t port;
// RAW ethertype
uint16_t ethertype;
// physical port to bind socket to
uint16_t physical_port;
} wr_sockaddr_t;
typedef struct {
uint32_t v[4];
} wr_picoseconds_t;
// Precise WhiteRabbit timestamp
// TS[picoseconds] = utc * 1e12 + nsec * 1e3 + phase;
PACKED struct _wr_timestamp {
// UTC time value (seconds)
int64_t utc;
// Nanoseconds
int32_t nsec;
// Phase (in picoseconds), linearized for receive timestamps, zero for send timestamps
int32_t phase; // phase(picoseconds)
int32_t raw_phase;
int32_t raw_nsec;
int32_t raw_ahead;
//int cntr_ahead;
};
typedef struct _wr_timestamp wr_timestamp_t;
/* OK. These functions we'll develop along with network card driver. You can write your own UDP-based stubs for testing purposes. */
// Initialization of network interface:
// - opens devices
// - does necessary ioctls()
// - initializes connection with the mighty HAL daemon
int ptpd_netif_init();
// Creates UDP or Ethernet RAW socket (determined by sock_type) bound to bind_addr. If PTPD_FLAG_MULTICAST is set, the socket is
// automatically added to multicast group. User can specify physical_port field to bind the socket to specific switch port only.
wr_socket_t *ptpd_netif_create_socket(int sock_type, int flags, wr_sockaddr_t *bind_addr);
// Sends a UDP/RAW packet (data, data_length) to address provided in wr_sockaddr_t.
// For raw frames, mac/ethertype needs to be provided, for UDP - ip/port.
// Every transmitted frame has assigned a tag value, stored at tag parameter. This value is later used
// for recovering the precise transmit timestamp. If user doesn't need it, tag parameter can be left NULL.
int ptpd_netif_sendto(wr_socket_t *sock, wr_sockaddr_t *to, void *data, size_t data_length, wr_timestamp_t *tx_ts);
// Receives an UDP/RAW packet. Data is written to (data) and length is returned. Maximum buffer length can be specified
// by data_length parameter. Sender information is stored in structure specified in 'from'. All RXed packets are timestamped and the timestamp
// is stored in rx_timestamp (unless it's NULL).
int ptpd_netif_recvfrom(wr_socket_t *sock, wr_sockaddr_t *from, void *data, size_t data_length, wr_timestamp_t *rx_timestamp);
// Closes the socket.
int ptpd_netif_close_socket(wr_socket_t *sock);
int ptpd_netif_poll(wr_socket_t*);
int ptpd_netif_get_hw_addr(wr_socket_t *sock, mac_addr_t *mac);
/*
* Function start HW locking of freq on WR Slave
* return:
* PTPD_NETIF_ERROR - locking not started
* PTPD_NETIF_OK - locking started
*/
int ptpd_netif_locking_enable(int txrx, const char *ifaceName);
/*
*
* return:
*
* PTPD_NETIF_OK - locking started
*/
int ptpd_netif_locking_disable(int txrx, const char *ifaceName);
int ptpd_netif_locking_poll(int txrx, const char *ifaceName);
/*
* Function turns on calibration (measurement of delay)
* Tx or Rx depending on the txrx param
* return:
* PTPD_NETIF_NOT_READY - if there is calibratin going on on another port
* PTPD_NETIF_OK - calibration started
*/
int ptpd_netif_calibrating_enable(int txrx, const char *ifaceName);
/*
* Function turns off calibration (measurement of delay)
* Tx or Rx depending on the txrx param
* return:
* PTPD_NETIF_ERROR - if there is calibratin going on on another port
* PTPD_NETIF_OK - calibration started
*/
int ptpd_netif_calibrating_disable(int txrx, const char *ifaceName);
/*
* Function checks if Rx/Tx (depending on the param) calibration is finished
* if finished, returns measured delay in delta
* return:
*
* PTPD_NETIF_OK - locking started
*/
int ptpd_netif_calibrating_poll(int txrx, const char *ifaceName, uint64_t *delta);
/*
* Function turns on calibration pattern.
* return:
* PTPD_NETIF_NOT_READY - if WRSW is busy with calibration on other switch or error occured
* PTPD_NETIF_OK - calibration started
*/
int ptpd_netif_calibration_pattern_enable(const char *ifaceName, unsigned int calibrationPeriod, unsigned int calibrationPattern, unsigned int calibrationPatternLen);
/*
* Function turns off calibration pattern
* return:
* PTPD_NETIF_ERROR - turning off not successful
* PTPD_NETIF_OK - turning off successful
*/
int ptpd_netif_calibration_pattern_disable(const char *ifaceName);
/*
* Function read calibration data if it's available, used at the beginning of PTPWRd to check if
* HW knows already the interface's deltax, and therefore no need for calibration
* return:
* PTPD_NETIF_NOT_FOUND - if deltas are not known
* PTPD_NETIF_OK - if deltas are known, in such case, deltaTx and deltaRx have valid data
*/
int ptpd_netif_read_calibration_data(const char *ifaceName, uint64_t *deltaTx, uint64_t *deltaRx);
#define MACIEK_TMP
#ifdef MACIEK_TMP
int ptpd_netif_select(wr_socket_t*);
int ptpd_netif_get_hw_addr(wr_socket_t *sock, mac_addr_t *mac);
#endif
/*
* Function reads state of the given port (interface in our case), if the port is up, everything is OK, otherwise ERROR
* return:
* PTPD_NETIF_ERROR - if the port is down
* PTPD_NETIF_OK - if the port is up
*/
int ptpd_netif_get_port_state(const char *ifaceName);
/*
* Function looks for a port (interface) for the port number 'number'
* it will return in the argument ifname the port name
* return:
* PTPD_NETIF_ERROR - port not found
* PTPD_NETIF_OK - if the port found
*/
int ptpd_netif_get_ifName(char *ifname, int number);
/* Returns the millisecond "tics" counter value */
uint64_t ptpd_netif_get_msec_tics();
#endif
// architecture-specific _do_call() functions
#ifdef __i386__
static int _do_call(void *func_ptr, void *args, int args_size)
{
int rval;
asm volatile (
"movl %%esp, %%edi\n"
"movl %%ebx, %%ecx\n"
"subl %%ebx, %%edi\n"
"shrl $2, %%ecx\n"
"cld\n"
"rep\n"
"movsl\n"
"subl %3, %%esp\n"
"call *%%eax\n"
"addl %3, %%esp\n"
: "=a"(rval)
: "a"(func_ptr), "S"(args), "b"(args_size)
:
);
/* "si", "di", "ax", "bx", "cx", "memory" */
return rval;
}
#endif
#ifdef __arm__
extern int _do_call(void *func_ptr, void *args, int args_size);
#endif
.global _do_call
_do_call:
stmfd sp!, {r4, r5, r6, r7, fp, lr}
mov r4, r1 // r4 = args_buffer
mov lr, r0 // lr = func_ptr
mov r5, r2 // r5 = args_size
ldr r0, [r4, #0]
ldr r1, [r4, #4]
ldr r2, [r4, #8]
ldr r3, [r4, #12]
mov fp, sp
sub r5, #16
cmp r5, #0
blt do_call
add r4, #16
mov r7, sp
sub r7, r5
sub sp, r5
copy_args:
ldr r6, [r4]
str r6, [r7]
add r7, #4
add r4, #4
sub r5, #4
cmp r5, #0
bne copy_args
do_call:
mov r6, lr
mov lr, pc
bx r6
mov sp, fp
ldmfd sp!, {r4, r5, r6, r7, fp, lr}
bx lr
struct test_struct {
int apples;
int peas;
char name[80];
float value;
};
struct state_struct {
char state_name[80];
float t;
int x;
};
void test_void(double *ptr, double a, double b)
{
*ptr = a+b;
}
main()
{
test_void(1000, 1.123, 2.245);
}
\ No newline at end of file
#include <stdio.h>
#include "wr_ipc.h"
#include "structs.h"
main()
{
wripc_handle_t cli;
int res_int;
float result, a,b;
struct state_struct s;
cli = wripc_connect("test");
wripc_call(cli, "bigfunc", &res_int, 8, A_INT32(1), A_INT32(2), A_INT32(3), A_INT32(4), A_INT32(5), A_INT32(6), A_INT32(7), A_INT32(8));
printf("1+...+8 = %d\n", res_int);
a=2.2; b= 4.4;
wripc_call(cli, "add", &result, 2, A_FLOAT(a), A_FLOAT(b));
printf("%.1f + %.1f = %.1f\n", a,b,result);
wripc_call(cli, "get_state", &s, 1, A_INT32(12345));
printf("state->name %s\n", s.state_name);
printf("state->t %.3f\n", s.t);
printf("state->x %d\n", s.x);
struct test_struct s2;
s2.apples = 10;
s2.peas = 15;
strcpy(s2.name, "Javier");
s2.value = 17.50;
// wripc_call(cli, "structure_test", &result, 1, A_STRUCT(s2));
wripc_call(cli, "string_test", &res_int, 3, A_STRING("Hello, world"), A_INT32(1), A_INT32(100));
printf("rval = %d\n", res_int);
usleep(1000);
wripc_close(cli);
}
float ret_float() { return 1.0; }
double ret_double() { return 1.0; }
void test_float(double a)
{
*(volatile double *) 0xdeadbee0 = a;
}
main()
{
float x = 123.345;
test_float(x);
}
\ No newline at end of file
#include <stdio.h>
#include <string.h>
#include "wr_ipc.h"
#include "structs.h"
int bigfunc(int a, int b, int c, int d, int e, int f, int g, int h)
{
printf("Call bigfunc: %d %d %d %d %d %d %d %d\n" ,a,b,c,d,e,f,g,h);
return a+b+c+d+e+f+g+h;
}
void add(float *rval, float a, float b)
{
printf("Call add: %.3f + %.3f\n", a,b);
*rval = a + b;
}
int string_test(char *string, int a, int b)
{
printf("Call string_test: a = %d, b= %d, string = '%s'\n", a,b,string);
return 12345;
}
void structure_test(struct test_struct *s)
{
printf("Call structure_test: %s got %d apples and %d peas of total value %.3f\n",s->name, s->apples, s->peas, s->value);
}
void get_state(struct state_struct *rval, int request)
{
printf("Call get_state: request = %d\n", request);
rval->t = 123.0;
strcpy(rval->state_name, "SomeState");
rval->x = request;
}
int main()
{
wripc_handle_t srv;
srv = wripc_create_server("test");
// add(10000, 1.0, 2.0);
wripc_export(srv, T_INT32, "bigfunc", bigfunc, 8, T_INT32, T_INT32, T_INT32, T_INT32, T_INT32, T_INT32, T_INT32, T_INT32 );
wripc_export(srv, T_FLOAT, "add", add, 2, T_FLOAT, T_FLOAT);
wripc_export(srv, T_INT32, "sub", add, 2, T_INT32, T_INT32);
wripc_export(srv, T_INT32, "string_test", string_test, 3, T_STRING, T_INT32, T_INT32);
wripc_export(srv, T_VOID, "structure_test", structure_test, 1, T_STRUCT(struct test_struct));
wripc_export(srv, T_STRUCT(struct state_struct), "get_state", get_state, 1, T_INT32);
for(;;) wripc_process(srv);
return 0;
}
This diff is collapsed.
#ifndef __WR_IPC_H
#define __WR_IPC_H
//#include <inttypes.h> -- now in ptpd-wrappers.h
#define T_INT32 1
#define T_INT16 2
#define T_INT8 3
#define T_STRING 4
#define T_FLOAT 5
#define T_DOUBLE 6
#define T_STRUCT_TYPE 7
#define T_STRUCT(type) (T_STRUCT_TYPE | (sizeof(type) << 8))
#define T_VOID 8
#define A_INT8(x) T_INT8,(x)
#define A_INT16(x) T_INT16,(x)
#define A_INT32(x) T_INT32,(x)
#define A_STRING(x) T_STRING,(x)
#define A_FLOAT(x) T_FLOAT,(x)
#define A_DOUBLE(x) T_DOUBLE,(x)
#define A_STRUCT(x) T_STRUCT(x),&x
#define WRIPC_ERROR_INVALID_REQUEST -1
#define WRIPC_ERROR_UNKNOWN_FUNCTION -2
#define WRIPC_ERROR_MALFORMED_PACKET -3
#define WRIPC_ERROR_INVALID_ARG -4
#define WRIPC_ERROR_NO_MEMORY -5
#define WRIPC_ERROR_TIMEOUT -6
#define WRIPC_ERROR_NETWORK_FAIL -7
typedef int wripc_handle_t;
wripc_handle_t wripc_create_server(const char *name);
wripc_handle_t wripc_connect(const char *name);
void wripc_close(wripc_handle_t h);
int wripc_export (wripc_handle_t handle, int rval_type, const char *name, void *func_ptr, int num_args, ...);
int wripc_call (wripc_handle_t handle, const char *name, void *rval, int num_args, ...);
int wripc_process(wripc_handle_t handle);
int wripc_publish_event(wripc_handle_t handle, int event_id, void *buf, int buf_len);
int wripc_subscribe_event(wripc_handle_t handle, int event_id);
int wripc_receive_event(wripc_handle_t handle, int *event_id, void *buf, int buf_len);
#endif
/*
* This header is used to hide all posix functions that can be hidden
*/
#ifndef __PTPD_WRAPPERS_H__
#define __PTPD_WRAPPERS_H__
#if __STDC_HOSTED__
/*
* The compiler is _not_ freestanding: we need to include some headers that
* are not available in the freestanding compilation, so are missing from
* source files.
*/
#include <stdint.h>
#else
#include <inttypes.h>
/*
* This is a freestanding compilation, and we may miss some data
* structures. For example misses <stdint.h>. Most likely it's
* because it's an old compiler version, so the #if may be wrong here.
*/
/* Looks like we miss <stdint.h>. Let's assume we are 32 bits */
/*typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
*/
/* Hmm... htons/htonl are missing. I made the Makefile check endianness */
#ifdef PTPD_MSBF
static inline uint16_t htons(uint16_t x) {return x;}
static inline uint32_t htonl(uint32_t x) {return x;}
static inline uint16_t ntohs(uint16_t x) {return x;}
#else
static inline uint16_t htons(uint16_t x) { return (x << 8) | (x >> 8); }
static inline uint32_t htonl(uint32_t x)
{ return htons(x>>16) | ((uint32_t)(htons(x) << 16));}
#endif /* endian */
/* usleep is not there in zpu */
extern int usleep(unsigned useconds);
/* The exports are not used in freestanding environment */
static inline void ptpd_init_exports() {}
static inline void ptpd_handle_wripc() {}
#define PPS_WIDTH 1000000
#define printf(x, ...) mprintf(x, ##__VA_ARGS__)
#define fprintf(file, x, ...) mprintf(x, ##__VA_ARGS__)
#define sprintf(buf, ...) msprintf(buf, __VA_ARGS__)
//#define DBG(x, ...) mprintf(x, ##__VA_ARGS__)
int usleep(unsigned useconds);
#endif /* hosted */
#endif /* __PTPD_WRAPPERS_H__ */
#ifndef __PTPD_EXPORTS_H
#define __PTPD_EXPORTS_H
#include <stdio.h>
#include <stdlib.h>
#include "ptpd.h"
typedef struct{
int valid;
char slave_servo_state[128];
char sync_source[128];
int tracking_enabled;
int64_t mu;
int64_t delay_ms;
int64_t delta_tx_m;
int64_t delta_rx_m;
int64_t delta_tx_s;
int64_t delta_rx_s;
int64_t fiber_asymmetry;
int64_t total_asymmetry;
int64_t cur_offset;
int64_t cur_setpoint;
int64_t cur_skew;
} ptpdexp_sync_state_t ;
#define PTPDEXP_COMMAND_TRACKING 1
#define PTPDEXP_COMMAND_MAN_ADJUST_PHASE 2
void ptpdexp_get_sync_state(ptpdexp_sync_state_t *state);
void ptpdexp_cmd(int cmd, int value);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment