Commit 438ed23b authored by julien.delange's avatar julien.delange
Browse files

* begin to handle x86/qemu


git-svn-id: https://tecsw.estec.esa.int/svn/taste/trunk/po-hi-c@744 129961e7-ef38-4bb5-a8f7-c9a525a55882
parent 1cf20937
......@@ -11,7 +11,9 @@
#ifndef __PO_HI_DRIVER_SOCKETS_H__
#define __PO_HI_DRIVER_SOCKETS_H__
#ifdef __PO_HI_NEED_DRIVER_SOCKETS
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) \
|| defined (__PO_HI_NEED_DRIVER_QEMU_NE2000_SOCKETS))
#include <po_hi_transport.h>
......@@ -32,6 +34,8 @@ void* __po_hi_sockets_receiver_task (void);
* and dispatch it in po-hi-c queues
*/
void* __po_hi_sockets_poller (void);
#endif
#endif
......
......@@ -17,7 +17,9 @@ typedef __po_hi_uint16_t __po_hi_inetport_t;
typedef char* __po_hi_inetaddr_t;
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) || defined (__PO_HI_NEED_DRIVER_SOCKETS_ASN1))
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) \
|| defined (__PO_HI_NEED_DRIVER_SOCKETS_ASN1) \
|| defined (__PO_HI_NEED_DRIVER_QEMU_NE2000_SOCKETS))
#define __PO_HI_NOPORT 1
#define __PO_HI_NOADDR ""
......
......@@ -27,24 +27,91 @@
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
#define CONFIGURE_MAXIMUM_POSIX_TIMERS 40
#define CONFIGURE_MAXIMUM_TIMERS 40
#define CONFIGURE_EXECUTIVE_RAM_SIZE (512*1024)
#define CONFIGURE_MAXIMUM_SEMAPHORES 20
#define CONFIGURE_MAXIMUM_TASKS 20
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 20
int POSIX_Init ();
#define CONFIGURE_MAXIMUM_POSIX_THREADS __PO_HI_NB_TASKS + 4
#define CONFIGURE_MAXIMUM_TASKS 16
#define CONFIGURE_MAXIMUM_POSIX_THREADS __PO_HI_NB_TASKS + 10
#define CONFIGURE_EXTRA_TASK_STACKS (20 * RTEMS_MINIMUM_STACK_SIZE)
#ifdef __PO_HI_NB_PORTS
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES __PO_HI_NB_TASKS + 2 + __PO_HI_NB_PORTS
#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES __PO_HI_NB_TASKS + 2 + __PO_HI_NB_PORTS
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES __PO_HI_NB_TASKS + 10 + __PO_HI_NB_PORTS
#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES __PO_HI_NB_TASKS + 10 + __PO_HI_NB_PORTS
#else
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES __PO_HI_NB_TASKS + 2 + __PO_HI_NB_PORTS
#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES __PO_HI_NB_TASKS + 2 + __PO_HI_NB_PORTS
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES __PO_HI_NB_TASKS + 10 + __PO_HI_NB_PORTS
#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES __PO_HI_NB_TASKS + 10 + __PO_HI_NB_PORTS
#endif
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
#include <po_hi_rtemsconfig.h>
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
// #include <po_hi_rtemsconfig.h>
#include <rtems/confdefs.h>
#endif
#endif /* RTEMS_POSIX */
#if defined (X86_RTEMS)
#include <rtems/rtems_bsdnet.h>
#include <bsp.h>
/*
* Loopback interface
*/
int rtems_bsdnet_loopattach(struct rtems_bsdnet_ifconfig*, int);
static struct rtems_bsdnet_ifconfig loopback_config = {
"lo0", /* name */
rtems_bsdnet_loopattach, /* attach function */
NULL, /* link to next interface */
"127.0.0.1", /* IP address */
"255.0.0.0", /* IP net mask */
};
/*
* Default network interface
*/
#define RTEMS_BSP_NETWORK_DRIVER_NAME "ne1"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_ne_driver_attach
struct rtems_bsdnet_ifconfig netdriver_config = {
RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */
RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */
&loopback_config, /* link to next interface */
"10.0.2.5", /* IP address */
"255.255.255.0", /* IP net mask */
NULL, /* Driver supplies hardware address */
0, /* Use default driver parameters */
0, /* mtu */
0, /* rbuf_count */
0, /* xbuf_count */
0, /* port */
9 /* irq */
};
/*
* Network configuration
*/
struct rtems_bsdnet_config rtems_bsdnet_config = {
&netdriver_config,
NULL,
0, /* Default network task priority */
256 * 1024, /* Default mbuf capacity */
256 * 1024, /* Default mbuf cluster capacity */
};
#endif /*(defined (X86_RTEMS) && defined (NEED_TRANSPORT)) */
#endif /* __COMMON_H__ */
......@@ -201,9 +201,20 @@ $(BINARY): generate-asn1-deployment target-objects check-rtems compile-po-hi $(U
$(make-exe)
cp $(BINARY) binary
ifeq ($(NEED_TRANSPORT), yes)
run: $(BINARY)
pidof qemu >/dev/null 2>&1 ; if [ $$? -eq 0 ]; then \
( sleep 5 ; qemu -net nic,model=ne2k_pci -net socket,connect=127.0.0.1:12345 -fda $(RUNTIME_PATH)/utils/x86-rtems-boot.img -hda fat:. -boot a ; )& \
echo "Launching QEMU in connect mode" ; \
else \
qemu -net nic,model=ne2k_pci -net socket,listen=127.0.0.1:12345 -fda $(RUNTIME_PATH)/utils/x86-rtems-boot.img -hda fat:. -boot a ; \
echo "Launching QEMU in listen mode" ; \
fi
else
run: $(BINARY)
qemu -fda $(RUNTIME_PATH)/utils/x86-rtems-boot.img -hda fat:. -boot a
endif
endif #NEED_TRANSPORT
endif #TARGET=x86qemu
ifeq ($(TARGET), nds.rtems)
OBJS = $(USER_OBJS) $(PO_HI_OBJS) $(GENERATED_OBJS) $(EXTERNAL_OBJECTS)
......
......@@ -22,11 +22,10 @@ CPP = i386-rtems4.8-g++
GPROF = i386-rtems4.8-gprof
TARGET_SOURCES =
#TARGET_TRANSPORT_SOURCES = $(RUNTIME_PATH)/config/leon-rtems/config.c
TARGET_TRANSPORT_SOURCES =
TARGET_CFLAGS = -DRTEMS_POSIX -DLEON_RTEMS
TARGET_INCLUDE = -I $(RUNTIME_PATH)/config/leon-rtems/
TARGET_CFLAGS = -DRTEMS_POSIX -DX86_RTEMS
TARGET_INCLUDE = -I $(RUNTIME_PATH)/config/
LD = i386-rtems4.8-ld
TARGET_LDFLAGS = -lrtemsbsp -lc
......
......@@ -12,7 +12,7 @@
#include <deployment.h>
#include <marshallers.h>
#ifdef __PO_HI_NEED_DRIVER_SOCKETS
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) || defined (__PO_HI_NEED_DRIVER_QEMU_NE2000_SOCKETS))
#include <po_hi_config.h>
#include <po_hi_task.h>
......@@ -147,7 +147,6 @@ int __po_hi_driver_sockets_send (__po_hi_entity_t from,
return __PO_HI_SUCCESS;
}
void* __po_hi_sockets_receiver_task (void)
{
socklen_t socklen = sizeof (struct sockaddr);
......@@ -167,6 +166,7 @@ void* __po_hi_sockets_receiver_task (void)
__po_hi_request_t received_request;
struct sockaddr_in sa;
max_socket = 0; /* Used to compute the max socket number, useful for listen() call */
/*
......@@ -186,14 +186,17 @@ void* __po_hi_sockets_receiver_task (void)
if (node != mynode )
{
sock = accept (nodes[mynode].socket, (struct sockaddr*) &sa, &socklen);
if (sock == -1)
{
__DEBUGMSG ("accept() failed, return=%d\n", sock);
}
if (read (sock, &node_init, sizeof (__po_hi_node_t)) != sizeof (__po_hi_node_t))
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Cannot read node-id for socket %d\n", sock);
#endif
continue;
}
rnodes[node].socket = sock;
if (sock > max_socket )
{
......@@ -303,5 +306,110 @@ void* __po_hi_sockets_receiver_task (void)
return NULL;
}
extern __po_hi_device_id my_id;
void* __po_hi_sockets_poller (void)
{
__DEBUGMSG ("Poller launched\n");
socklen_t socklen = sizeof (struct sockaddr);
/* See ACCEPT (2) for details on initial value of socklen */
__po_hi_uint32_t len;
int sock;
int max_socket;
fd_set selector;
struct sockaddr_in sa;
__po_hi_node_t dev;
__po_hi_node_t dev_init;
__po_hi_request_t received_request;
__po_hi_msg_t msg;
max_socket = 0; /* Used to compute the max socket number, useful for listen() call */
/*
* We initialize each node socket with -1 value. This value means
* that the socket is not active.
*/
for (dev = 0 ; dev < __PO_HI_NB_DEVICES ; dev++)
{
rnodes[dev].socket = -1;
}
/*
* Create a socket for each node that will communicate with us.
*/
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
{
if (dev != my_id)
{
sock = accept (nodes[my_id].socket, (struct sockaddr*) &sa, &socklen);
if (read (sock, &dev_init, sizeof (__po_hi_device_id)) != sizeof (__po_hi_device_id))
{
__DEBUGMSG ("[DRIVER SOCKETS] Cannot read device-id for device %d, socket=%d\n", dev, sock);
continue;
}
__DEBUGMSG ("[DRIVER SOCKETS] read device-id %d from socket=%d\n", dev_init, sock);
rnodes[dev].socket = sock;
if (sock > max_socket )
{
max_socket = sock;
}
}
}
__DEBUGMSG ("[DRIVER SOCKETS] Poller initialization finished\n");
__po_hi_wait_initialization ();
/*
* Then, listen and receive data on the socket, identify the node
* which send the data and put it in its message queue
*/
while (1)
{
FD_ZERO( &selector );
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
{
if ( (dev != my_id ) && ( rnodes[dev].socket != -1 ) )
{
FD_SET( rnodes[dev].socket , &selector );
}
}
if (select (max_socket + 1, &selector, NULL, NULL, NULL) == -1 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("[DRIVER SOCKETS] Error on select for node %d\n", mynode);
#endif
}
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("[DRIVER SOCKETS] Receive message\n");
#endif
for (dev = 0; dev < __PO_HI_NB_DEVICES ; dev++)
{
if ( (rnodes[dev].socket != -1 ) && FD_ISSET(rnodes[dev].socket, &selector))
{
__DEBUGMSG ("[DRIVER SOCKETS] Receive message from dev %d\n", dev);
memset (msg.content, '\0', __PO_HI_MESSAGES_MAX_SIZE);
len = recv (rnodes[dev].socket, msg.content, __PO_HI_MESSAGES_MAX_SIZE, MSG_WAITALL);
__DEBUGMSG ("[DRIVER SOCKETS] Message received len=%d\n",len);
if (len == 0)
{
rnodes[dev].socket = -1;
continue;
}
__po_hi_unmarshall_request (&received_request, &msg);
__po_hi_main_deliver (&received_request);
}
}
}
return NULL;
}
#endif
......@@ -10,7 +10,11 @@
#include <deployment.h>
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) || defined (__PO_HI_NEED_DRIVER_SOCKETS_ASN1))
#if (defined (__PO_HI_NEED_DRIVER_SOCKETS) \
|| defined (__PO_HI_NEED_DRIVER_SOCKETS_ASN1) \
|| defined (__PO_HI_NEED_DRIVER_QEMU_NE2000_SOCKETS))
#include <activity.h>
......@@ -28,7 +32,6 @@
#include <po_hi_debug.h>
#include <po_hi_transport.h>
#include <po_hi_common.h>
#include <po_hi_main.h>
#include <po_hi_time.h>
#include <po_hi_task.h>
......@@ -76,7 +79,7 @@ void __po_hi_driver_sockets_init (__po_hi_device_id id)
dev_conf = __po_hi_get_device_naming (id);
dev_port = 0;
if (sscanf (dev_conf, "eth %s %d", dev_addr, &dev_port) == 0)
if (sscanf (dev_conf, "ip %s %d", dev_addr, &dev_port) == 0)
{
__DEBUGMSG ("[DRIVER SOCKETS] Unable to parse device configuration (id=%d)\n", id);
}
......@@ -151,7 +154,7 @@ void __po_hi_driver_sockets_init (__po_hi_device_id id)
dev_conf = __po_hi_get_device_naming (dev);
if (sscanf (dev_conf, "eth %s %d", dev_addr, &dev_port) == 0)
if (sscanf (dev_conf, "ip %s %d", dev_addr, &dev_port) == 0)
{
__DEBUGMSG ("[DRIVER SOCKETS] Unable to parse device configuration (id=%d)\n", id);
continue;
......@@ -237,7 +240,9 @@ void __po_hi_driver_sockets_init (__po_hi_device_id id)
}
}
}
#else
#endif
#ifdef __PO_HI_NEED_DRIVER_SOCKETS
void __po_hi_driver_sockets_init (__po_hi_device_id id)
{
int i;
......@@ -398,5 +403,223 @@ void __po_hi_driver_sockets_init (__po_hi_device_id id)
}
#endif
#ifdef __PO_HI_NEED_DRIVER_QEMU_NE2000_SOCKETS
#include <bsp.h>
#include <rtems/rtems_bsdnet.h>
extern struct rtems_bsdnet_ifconfig netdriver_config;
char ethernet_address[6] = { 0x00, 0x80, 0x7F, 0x22, 0x61, 0x77};
void __po_hi_driver_sockets_init (__po_hi_device_id id)
{
int i;
int ret;
int reuse;
char *tmp;
__po_hi_uint16_t dev;
__po_hi_time_t mytime;
struct sockaddr_in sa;
struct hostent* hostinfo;
char* dev_conf;
char dev_addr[16];
int dev_port;
int node;
my_id = id;
memset (dev_addr, '\0', 16);
for (node = 0 ; node < __PO_HI_NB_DEVICES ; node++)
{
nodes[node].socket = -1;
}
dev_conf = __po_hi_get_device_naming (id);
dev_port = 0;
if (sscanf (dev_conf, "ip %s %d", dev_addr, &dev_port) == 0)
{
__DEBUGMSG ("[DRIVER SOCKETS] Unable to parse device configuration (id=%d)\n", id);
}
__DEBUGMSG ("My configuration, addr=%s, port=%d\n", dev_addr, dev_port);
memset (netdriver_config.ip_address, '\0', 15);
memcpy (netdriver_config.ip_address, dev_addr, strlen (dev_addr));
__DEBUGMSG ("Set configuration addr for RTEMS=%s\n", netdriver_config.ip_address);
ethernet_address[5] = (dev_port + 23) % 254;
netdriver_config.hardware_address = ethernet_address;
__DEBUGMSG ("Init RTEMS\n");
if (rtems_bsdnet_initialize_network () != RTEMS_SUCCESSFUL)
{
__DEBUGMSG ("Error when initializing RTEMS network\n");
return;
}
__DEBUGMSG ("RTEMS network init done\n");
/*
* If the current node port has a port number, then it has to
* listen to other nodes. So, we create a socket, bind it and
* listen to other nodes.
*/
if (dev_port != 0)
{
nodes[id].socket = socket (AF_INET, SOCK_STREAM, 0);
if (nodes[id].socket == -1 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Cannot create socket for device %d\n", id);
#endif
return;
}
reuse = 1;
setsockopt (nodes[id].socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof (reuse));
sa.sin_addr.s_addr = htonl (INADDR_ANY); /* We listen on all adresses */
sa.sin_family = AF_INET;
sa.sin_port = htons (dev_port); /* Port provided by the generated code */
if( bind( nodes[id].socket , ( struct sockaddr * ) &sa , sizeof( struct sockaddr_in ) ) < 0 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Unable to bind socket and port on socket %d\n", nodes[id].socket);
#endif
return;
}
__DEBUGMSG ("Bind socket, success\n");
if( listen( nodes[id].socket , __PO_HI_NB_ENTITIES ) < 0 )
{
#ifdef __PO_HI_DEBUG
__DEBUGMSG ("Cannot listen on socket %d\n", nodes[mynode].socket);
#endif
return;
}
__DEBUGMSG ("Listen on socket, success\n");
__po_hi_initialize_add_task ();
__po_hi_create_generic_task
(-1, 0,__PO_HI_MAX_PRIORITY, 0, __po_hi_sockets_poller);
}
/*
* For each node in the sytem that may communicate with the current
* node we create a socket. This socket will be used to send data.
*/
for (dev = 0 ; dev < __PO_HI_NB_DEVICES ; dev++ )
{
if (dev == id)
{
continue;
}
__DEBUGMSG ("[DRIVER SOCKETS] Will initialize connection with device %d\n", dev);
memset (dev_addr, '\0', 16);
dev_port = 0;
dev_conf = __po_hi_get_device_naming (dev);
if (sscanf (dev_conf, "ip %s %d", dev_addr, &dev_port) == 0)
{
__DEBUGMSG ("[DRIVER SOCKETS] Unable to parse device configuration (id=%d)\n", id);
continue;
}
__DEBUGMSG ("[DRIVER SOCKETS] Configuration for device %d, addr=%s, port=%d\n", dev, dev_addr, dev_port);
if (dev_port == 0)
{
__DEBUGMSG ("[DRIVER SOCKETS] Invalid remote port\n");
continue;
}
while (1)
{
nodes[dev].socket = socket (AF_INET, SOCK_STREAM, 0);
if (nodes[dev].socket == -1 )
{
__DEBUGMSG ("[DRIVER SOCKETS] Socket for node %d is not created", node);
return;
}
hostinfo = gethostbyname ((char*)dev_addr);
if (hostinfo == NULL )
{
__DEBUGMSG ("[DRIVER SOCKETS] Error while getting host informations for device %d\n", dev);
}
sa.sin_port = htons (dev_port);
sa.sin_family = AF_INET;
/* The following lines are used to copy the
* hostinfo->h_length to the sa.sin_addr member. Most
* of program use the memcpy to do that, but the
* RT-POSIX profile we use forbid the use of this
* function. We use a loop instead to perform the
* copy. So, these lines replace the code :
*
* memcpy( (char*) &( sa.sin_addr ) , (char*)hostinfo->h_addr , hostinfo->h_length );
*/
tmp = (char*) &(sa.sin_addr);
for (i=0 ; i<hostinfo->h_length ; i++)
{
tmp[i] = hostinfo->h_addr[i];
}
/*
* We try to connect on the remote host. We try every
* second to connect on.
*/
ret = connect (nodes[dev].socket,
(struct sockaddr*) &sa ,
sizeof (struct sockaddr_in));
if (ret == 0)
{
__DEBUGMSG ("[DRIVER SOCKETS] Send my id (%d)\n", id);
if (write (nodes[dev].socket, &id, sizeof (__po_hi_device_id)) != sizeof (__po_hi_device_id))
{
__DEBUGMSG ("[DRIVER SOCKETS] Device %d cannot send his id\n", id);
}
break;
}
if (close (nodes[dev].socket))
{
__DEBUGMSG ("[DRIVER SOCKETS] Cannot close socket %d\n", nodes[dev].socket);
}
/*
* We wait 500ms each time we try to connect on the
* remote host
*/
__po_hi_get_time (&mytime);
__DEBUGMSG ("[DRIVER SOCKETS] Cannot connect on device %d, wait 2s\n", dev);
__po_hi_delay_until (__po_hi_add_times (mytime, __po_hi_milliseconds (2000)));
}
}
}
#endif
#endif /* __PO_HI_NEED_DRIVER_SOCKETS || __PO_HI_NEED_DRIVER_SOCKETS_ASN1 */
......@@ -40,6 +40,8 @@ void __po_hi_initialize_add_task ()
int __po_hi_initialize ()
{
pthread_mutexattr_t mutex_attr;
#ifdef RTEMS_POSIX
#include <rtems/rtems/clock.h>
rtems_status_code status;
......@@ -57,8 +59,19 @@ int __po_hi_initialize ()
#endif
if (pthread_mutex_init (&mutex_init, NULL) != 0 )
if (pthread_mutexattr_init (&mutex_attr) != 0)
{
__DEBUGMSG ("[MAIN] Unable to init mutex attributes\n");
}
if (pthread_mutexattr_setprioceiling (&mutex_attr, 50) != 0)
{
__DEBUGMSG ("[MAIN] Unable to set priority ceiling on mutex\n");
}
if (pthread_mutex_init (&mutex_init, &mutex_attr) != 0 )