Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
EtherBone Core
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Projects
EtherBone Core
Commits
4b87fc1b
Commit
4b87fc1b
authored
13 years ago
by
Wesley W. Terpstra
Browse files
Options
Downloads
Patches
Plain Diff
Skeleton test bench in C++
parent
ad11016b
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
api/v2/Makefile
+4
-1
4 additions, 1 deletion
api/v2/Makefile
api/v2/etherbone.h
+47
-17
47 additions, 17 deletions
api/v2/etherbone.h
api/v2/glue/cplusplus.cpp
+13
-1
13 additions, 1 deletion
api/v2/glue/cplusplus.cpp
api/v2/test/loopback.cpp
+173
-0
173 additions, 0 deletions
api/v2/test/loopback.cpp
with
237 additions
and
19 deletions
api/v2/Makefile
+
4
−
1
View file @
4b87fc1b
...
...
@@ -9,7 +9,7 @@ CXXFLAGS= $(FLAGS)
CC
=
gcc
CXX
=
g++
TARGETS
=
demo/sizes demo/eb-read demo/eb-write demo/eb-snoop
TARGETS
=
demo/sizes demo/eb-read demo/eb-write demo/eb-snoop
test
/loopback
TARGET
=
etherbone.a
OBJECTS
=
$(
patsubst %.cpp,%.o,
$(
patsubst %.c,%.o,
$(
SOURCES
)))
SOURCES
=
memory/static.c
\
...
...
@@ -43,6 +43,9 @@ $(TARGET): $(OBJECTS)
demo/%
:
demo/%.c $(TARGET)
$(
CC
)
$(
CFLAGS
)
-o
$@
$^
test/%
:
test/%.cpp $(TARGET)
$(
CXX
)
$(
CXXFLAGS
)
-o
$@
$^
clean
:
rm
-f
$(
TARGET
)
$(
OBJECTS
)
$(
TARGETS
)
...
...
This diff is collapsed.
Click to expand it.
api/v2/etherbone.h
+
47
−
17
View file @
4b87fc1b
...
...
@@ -409,7 +409,12 @@ typedef eb_data_t data_t;
typedef
eb_status_t
status_t
;
typedef
eb_width_t
width_t
;
typedef
eb_descriptor_t
descriptor_t
;
typedef
eb_handler_t
handler_t
;
class
Handler
{
public:
virtual
status_t
read
(
address_t
address
,
width_t
width
,
data_t
*
data
)
=
0
;
virtual
status_t
write
(
address_t
address
,
width_t
width
,
data_t
data
)
=
0
;
};
class
Socket
{
public:
...
...
@@ -419,7 +424,7 @@ class Socket {
status_t
close
();
/* attach/detach a virtual device */
status_t
attach
(
h
andler
_t
handler
);
status_t
attach
(
address_t
base
,
address_t
mask
,
H
andler
*
handler
);
status_t
detach
(
address_t
address
);
status_t
poll
();
...
...
@@ -445,7 +450,8 @@ class Device {
status_t
close
();
void
flush
();
Socket
socket
()
const
;
const
Socket
socket
()
const
;
Socket
socket
();
protected:
Device
(
eb_device_t
device
);
...
...
@@ -471,7 +477,8 @@ class Cycle {
Cycle
&
read_config
(
address_t
address
,
data_t
*
data
=
0
);
Cycle
&
write_config
(
address_t
address
,
data_t
data
);
Device
device
()
const
;
const
Device
device
()
const
;
Device
device
();
protected:
eb_cycle_t
cycle
;
...
...
@@ -493,19 +500,20 @@ class Operation {
address_t
address
()
const
;
data_t
data
()
const
;
Operation
next
()
const
;
const
Operation
next
()
const
;
Operation
next
();
protected:
Operation
(
eb_operation_t
op
);
eb_operation_t
operation
;
};
/* Convenience templates to convert member functions into callback type */
template
<
typename
T
,
void
(
T
::*
cb
)(
Operation
,
status_t
)>
void
proxy
(
T
*
object
,
eb_operation_t
op
,
eb_status_t
status
)
{
return
(
object
->*
cb
)(
Operation
(
op
),
status
);
}
/* Convenience templates to convert member functions into callback type */
template
<
typename
T
,
void
(
T
::*
cb
)(
Operation
,
status_t
)>
friend
void
proxy
(
T
*
object
,
eb_operation_t
op
,
eb_status_t
status
)
{
return
(
object
->*
cb
)(
Operation
(
op
),
status
);
}
};
/****************************************************************************/
/* C++ Implementation */
...
...
@@ -529,8 +537,18 @@ inline status_t Socket::close() {
return
out
;
}
inline
status_t
Socket
::
attach
(
handler_t
handler
)
{
return
eb_socket_attach
(
socket
,
handler
);
/* Proxy */
eb_status_t
eb_proxy_read_handler
(
eb_user_data_t
data
,
eb_address_t
address
,
eb_width_t
width
,
eb_data_t
*
ptr
);
eb_status_t
eb_proxy_write_handler
(
eb_user_data_t
data
,
eb_address_t
address
,
eb_width_t
width
,
eb_data_t
value
);
inline
status_t
Socket
::
attach
(
address_t
base
,
address_t
mask
,
Handler
*
handler
)
{
struct
eb_handler
h
;
h
.
base
=
base
;
h
.
mask
=
mask
;
h
.
data
=
handler
;
h
.
read
=
&
eb_proxy_read_handler
;
h
.
write
=
&
eb_proxy_write_handler
;
return
eb_socket_attach
(
socket
,
&
h
);
}
inline
status_t
Socket
::
detach
(
address_t
address
)
{
...
...
@@ -571,10 +589,14 @@ inline status_t Device::close() {
return
out
;
}
inline
Socket
Device
::
socket
()
const
{
inline
const
Socket
Device
::
socket
()
const
{
return
Socket
(
eb_device_socket
(
device
));
}
inline
Socket
Device
::
socket
()
{
return
Socket
(
eb_device_socket
(
device
));
}
inline
void
Device
::
flush
()
{
return
eb_device_flush
(
device
);
}
...
...
@@ -625,7 +647,11 @@ inline Cycle& Cycle::write_config(address_t address, data_t data) {
return
*
this
;
}
inline
Device
Cycle
::
device
()
const
{
inline
const
Device
Cycle
::
device
()
const
{
return
Device
(
eb_cycle_device
(
cycle
));
}
inline
Device
Cycle
::
device
()
{
return
Device
(
eb_cycle_device
(
cycle
));
}
...
...
@@ -657,7 +683,11 @@ inline data_t Operation::data() const {
return
eb_operation_data
(
operation
);
}
inline
Operation
Operation
::
next
()
const
{
inline
Operation
Operation
::
next
()
{
return
Operation
(
eb_operation_next
(
operation
));
}
inline
const
Operation
Operation
::
next
()
const
{
return
Operation
(
eb_operation_next
(
operation
));
}
...
...
This diff is collapsed.
Click to expand it.
api/v2/glue/cplusplus.cpp
+
13
−
1
View file @
4b87fc1b
...
...
@@ -27,7 +27,7 @@
#include
"../etherbone.h"
using
namespace
etherbone
;
namespace
etherbone
{
static
void
eb_descriptor_push
(
eb_user_data_t
data
,
eb_descriptor_t
des
)
{
std
::
vector
<
descriptor_t
>*
out
=
(
std
::
vector
<
descriptor_t
>*
)
data
;
...
...
@@ -39,3 +39,15 @@ std::vector<descriptor_t> Socket::descriptor() const {
eb_socket_descriptor
(
socket
,
&
out
,
&
eb_descriptor_push
);
return
out
;
}
eb_status_t
eb_proxy_read_handler
(
eb_user_data_t
data
,
eb_address_t
address
,
eb_width_t
width
,
eb_data_t
*
ptr
)
{
Handler
*
handler
=
reinterpret_cast
<
Handler
*>
(
data
);
return
handler
->
read
(
address
,
width
,
ptr
);
}
eb_status_t
eb_proxy_write_handler
(
eb_user_data_t
data
,
eb_address_t
address
,
eb_width_t
width
,
eb_data_t
value
)
{
Handler
*
handler
=
reinterpret_cast
<
Handler
*>
(
data
);
return
handler
->
write
(
address
,
width
,
value
);
}
}
This diff is collapsed.
Click to expand it.
api/v2/test/loopback.cpp
0 → 100644
+
173
−
0
View file @
4b87fc1b
/** @file loopback.cpp
* @brief A test program which executes many many EB queries.
*
* Copyright (C) 2011-2012 GSI Helmholtz Centre for Heavy Ion Research GmbH
*
* All Etherbone object types are opaque in this interface.
* Only those methods listed in this header comprise the public interface.
*
* @author Wesley W. Terpstra <w.terpstra@gsi.de>
*
* @bug None!
*
*******************************************************************************
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<vector>
#include
<algorithm>
#include
"../etherbone.h"
using
namespace
etherbone
;
using
namespace
std
;
void
die
(
const
char
*
why
,
status_t
error
);
void
test_query
(
Device
device
,
int
len
,
int
requests
);
void
test_width
(
Socket
socket
,
width_t
width
);
void
die
(
const
char
*
why
,
status_t
error
)
{
fprintf
(
stderr
,
"%s: %s
\n
"
,
why
,
eb_status
(
error
));
exit
(
1
);
}
enum
RecordType
{
READ_BUS
,
READ_CFG
,
WRITE_BUS
,
WRITE_CFG
};
struct
Record
{
address_t
address
;
data_t
data
;
bool
error
;
RecordType
type
;
};
class
Echo
:
public
Handler
{
public:
status_t
read
(
address_t
address
,
width_t
width
,
data_t
*
data
);
status_t
write
(
address_t
address
,
width_t
width
,
data_t
data
);
};
status_t
Echo
::
read
(
address_t
address
,
width_t
width
,
data_t
*
data
)
{
return
EB_OK
;
}
status_t
Echo
::
write
(
address_t
address
,
width_t
width
,
data_t
data
)
{
return
EB_OK
;
}
class
TestCycle
{
public:
std
::
vector
<
Record
>
records
;
int
*
success
;
TestCycle
(
Device
device
,
int
length
,
int
*
success
);
void
complete
(
Operation
op
,
status_t
status
);
};
void
TestCycle
::
complete
(
Operation
op
,
status_t
status
)
{
for
(
unsigned
i
=
0
;
i
<
records
.
size
();
++
i
)
{
Record
&
r
=
records
[
i
];
if
(
op
.
is_null
())
die
(
"unexpected null op"
,
EB_FAIL
);
switch
(
r
.
type
)
{
case
READ_BUS
:
if
(
!
op
.
is_read
()
||
op
.
is_config
())
die
(
"wrong op"
,
EB_FAIL
);
break
;
case
READ_CFG
:
if
(
!
op
.
is_read
()
||
!
op
.
is_config
())
die
(
"wrong op"
,
EB_FAIL
);
break
;
case
WRITE_BUS
:
if
(
op
.
is_read
()
||
op
.
is_config
())
die
(
"wrong op"
,
EB_FAIL
);
break
;
case
WRITE_CFG
:
if
(
op
.
is_read
()
||
!
op
.
is_config
())
die
(
"wrong op"
,
EB_FAIL
);
break
;
}
if
(
op
.
address
()
!=
r
.
address
)
die
(
"wrong addr"
,
EB_FAIL
);
if
(
op
.
data
()
!=
r
.
data
)
die
(
"wrong data"
,
EB_FAIL
);
if
(
op
.
had_error
()
!=
r
.
error
)
die
(
"wrong flag"
,
EB_FAIL
);
}
if
(
!
op
.
is_null
())
die
(
"too many ops"
,
EB_FAIL
);
}
TestCycle
::
TestCycle
(
Device
device
,
int
length
,
int
*
success_
)
:
success
(
success_
)
{
Cycle
cycle
(
device
,
this
,
&
proxy
<
TestCycle
,
&
TestCycle
::
complete
>
);
for
(
int
op
=
0
;
op
<
length
;
++
op
)
{
Record
r
;
switch
(
r
.
type
)
{
case
READ_BUS
:
cycle
.
read
(
r
.
address
,
0
);
break
;
case
READ_CFG
:
cycle
.
read_config
(
r
.
address
,
0
);
break
;
case
WRITE_BUS
:
cycle
.
write
(
r
.
address
,
r
.
data
);
break
;
case
WRITE_CFG
:
cycle
.
write_config
(
r
.
address
,
r
.
data
);
break
;
}
records
.
push_back
(
r
);
}
}
void
test_query
(
Device
device
,
int
len
,
int
requests
)
{
std
::
vector
<
int
>
cuts
;
std
::
vector
<
int
>::
iterator
i
;
int
success
,
timeout
;
cuts
.
push_back
(
0
);
cuts
.
push_back
(
len
);
for
(
int
cut
=
1
;
cut
<
requests
;
++
cut
)
cuts
.
push_back
(
random
()
%
len
);
sort
(
cuts
.
begin
(),
cuts
.
end
());
/* Prepare each cycle */
for
(
i
=
cuts
.
begin
();
i
+
1
!=
cuts
.
end
();
++
i
)
{
int
amount
=
*
(
i
+
1
)
-
*
i
;
TestCycle
(
device
,
amount
,
&
success
);
}
/* Flush the queries */
device
.
flush
();
/* Wait until all complete successfully */
timeout
=
1000000
;
/* 1 second */
Socket
socket
=
device
.
socket
();
while
(
success
<
requests
&&
timeout
>
0
)
{
timeout
-=
socket
.
block
(
timeout
);
socket
.
poll
();
}
if
(
timeout
<
0
)
die
(
"waiting for loopback success"
,
EB_TIMEOUT
);
}
void
test_width
(
Socket
socket
,
width_t
width
)
{
Device
device
;
status_t
err
;
if
((
err
=
device
.
open
(
socket
,
"udp/localhost/8183"
,
width
))
!=
EB_OK
)
die
(
"device.open"
,
err
);
for
(
int
len
=
0
;
len
<
4000
;
++
len
)
for
(
int
requests
=
0
;
requests
<=
9
;
++
requests
)
for
(
int
repetitions
=
0
;
repetitions
<
100
;
++
repetitions
)
test_query
(
device
,
len
,
requests
);
if
((
err
=
device
.
close
())
!=
EB_OK
)
die
(
"device.close"
,
err
);
}
int
main
()
{
status_t
err
;
Socket
socket
;
if
((
err
=
socket
.
open
(
8183
))
!=
EB_OK
)
die
(
"socket.open"
,
err
);
Echo
echo
;
if
((
err
=
socket
.
attach
(
0
,
~
0
,
&
echo
))
!=
EB_OK
)
die
(
"socket.attach"
,
err
);
/* for widths */
test_width
(
socket
,
EB_DATAX
|
EB_ADDRX
);
return
0
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment