From 7272062cee1f62854544d95458359a1b957cdf05 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Mon, 18 Jun 2012 18:43:59 +0200 Subject: *add tests *add debug setting *modify header comments --- Makefile | 24 ++++----- README.md | 8 +-- src/Makefile | 16 ++++-- src/benchmark.c | 40 ++++++++++++++ src/k8055.c | 18 ++++--- src/k8055.h | 17 +++++- src/test.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 251 insertions(+), 30 deletions(-) create mode 100644 src/benchmark.c create mode 100644 src/test.c diff --git a/Makefile b/Makefile index 3b5046b..93d86bc 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,5 @@ -PREFIX = /usr/local - -#run this if you want to build everything but not install user-wide or system-wide -local: compile copy +DESTDIR= +PREFIX=$(DESTDIR)/usr compile: make -C src @@ -22,29 +20,27 @@ mkdirs: doc: mkdirs doxygen Doxyfile +#run this if you want to build everything but not install user-wide or system-wide +local: compile copy + #these commands must be run as root install-rules: - cp k8055.rules /etc/udev/rules.d/k8055.rules + cp k8055.rules $(DESTDIR)/etc/udev/rules.d/k8055.rules uninstall-rules: - rm /etc/udev/rules.d/k8055.rules + rm $(DESTDIR)/etc/udev/rules.d/k8055.rules install-permissions: install-rules - groupadd -rf k8055 + groupadd -f k8055 $(foreach user, $(USERS), usermod -a -G k8055 $(user);) uninstall-permissions: uninstall-rules groupdel k8055 -install-product: compile +install: compile cp src/*.so $(PREFIX)/lib cp src/*.h $(PREFIX)/include -uninstall-product: +uninstall: rm $(PREFIX)/lib/libk8055.so rm $(PREFIX)/include/k8055.h - -install: install-product install-permissions - -uninstall: uninstall-permissions uninstall-product - diff --git a/README.md b/README.md index bc0ad8f..18c2a1e 100644 --- a/README.md +++ b/README.md @@ -37,13 +37,9 @@ The previously described steps may be automated by running ```make install-rules To uninstall, run ```make uninstall-rules``` or ```make uninstall-permissions```. ### System install -Run ```make install-product``` to install the library and header files (this command does essentially the same as a local build with the exception that products are copied to /usr/local/ by default). You may change that path by passing 'make' the variable 'PREFIX', i.e. ```make install PREFIX=/my/custom/path```. To uninstall, run ```make uninstall-product```. +Run ```make install``` to install the library and header files (this command does essentially the same as a local build with the exception that products are copied to /usr/local/ by default). You may change that path by passing 'make' the variable 'PREFIX', i.e. ```make install PREFIX=/my/custom/path```. To uninstall, run ```make uninstall```. -Note that the above commands only install/uninstall the library and header files, udev configuration is not performed. To perform a complete installation and udev configuration, run the command - - make install USERS="" - -Uninstallation is done by ```make uninstall```. +Note that the above commands only install/uninstall the library and header files, udev configuration is not performed. ## Documentation diff --git a/src/Makefile b/src/Makefile index 0e1d62b..cb3818d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,16 +1,26 @@ C = gcc # libusb.h location -INCDIR = /usr/include/libusb-1.0 CFLAGS = -std=c99 -O2 -Wall all: libk8055.so libk8055.so: k8055.o - $(C) -shared -o libk8055.so k8055.o -lusb-1.0 + $(C) -shared -o libk8055.so k8055.o -lusb-1.0 -lm + + +libk8055.a: k8055.o + $(C) -o libk8055.a k8055.o -lusb-1.0 -lm k8055.o: k8055.c - $(C) $(CFLAGS) -fPIC -I $(INCDIR) -c k8055.c -o k8055.o + $(C) $(CFLAGS) -fPIC -c k8055.c -o k8055.o clean: rm -rf *.o rm -rf *.so + rm -rf k8055-* + +test: k8055.c test.c + $(C) test.c k8055.c -o k8055-test $(CFLAGS) -D_POSIX_C_SOURCE=199309L -lusb-1.0 -lm + +benchmark: k8055.c benchmark.c + $(C) benchmark.c k8055.c -o k8055-benchmark $(CFLAGS) -D_POSIX_C_SOURCE=199309L -lusb-1.0 -lm diff --git a/src/benchmark.c b/src/benchmark.c new file mode 100644 index 0000000..185e738 --- /dev/null +++ b/src/benchmark.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include "k8055.h" + + +#define ITERATIONS 1000 + +int main(int argc, char *argv[]) { + int port; + if (argc <= 1) port = 0; + else port = atoi(argv[1]); + + k8055_device* device; + if (k8055_open_device(port, &device) != 0) { + printf("could not open board on port %i\n", port); + return -1; + }; + + struct timeval t0; + struct timeval t; + + int us = 0; + for (int i = 0; i < ITERATIONS; ++i) { + gettimeofday(&t0, NULL); + k8055_get_all_input(device, NULL, NULL, NULL, NULL, NULL, false); + gettimeofday(&t, NULL); + us += (t.tv_sec - t0.tv_sec) * 1000000 + t.tv_usec - t0.tv_usec; + } + printf("average read time for %i iterations: %i [ms]\n", ITERATIONS, us / ITERATIONS / 1000); + + us = 0; + for (int i = 0; i < ITERATIONS; ++i) { + gettimeofday(&t0, NULL); + k8055_get_all_input(device, NULL, NULL, NULL, NULL, NULL, true); + gettimeofday(&t, NULL); + us += (t.tv_sec - t0.tv_sec) * 1000000 + t.tv_usec - t0.tv_usec; + } + printf("average quick read time for %i iterations: %i [ms]\n", ITERATIONS, us / ITERATIONS / 1000); +} diff --git a/src/k8055.c b/src/k8055.c index 5b8f806..e031ec3 100644 --- a/src/k8055.c +++ b/src/k8055.c @@ -26,7 +26,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Thanks to the following people who wrote the original version of `libk8055' - (http://libk8055.sourceforge.net/): + (http://libk8055.sourceforge.net/), without their useful comments this + library would not have been possible: 2005 by Sven Lindberg @@ -34,7 +35,8 @@ Commenting, general rearrangement of code, bugfixes, python interface with swig and simple k8055 python class - The comments explaining the data packets and debounce time conversion are from them. + The comments explaining the data packets and debounce time conversion + (in the source file) are from them. Input packet format @@ -126,7 +128,7 @@ #include #include #include -#include +#include #include "k8055.h" /** Represents a Vellemean K8055 USB board. */ @@ -147,12 +149,16 @@ struct k8055_device { /** Libusb context. */ static libusb_context* context = NULL; static int k8055_open_devices = 0; -static int DEBUG = 0; +static int debug = 0; + +void k8055_debug(bool value) { + debug = value; +} /** Prints the given message to standard output if debugging is enabled. */ static void print_error(const char * str) { - if (DEBUG) { - printf("%s", str); + if (debug) { + printf("%s\n", str); } } diff --git a/src/k8055.h b/src/k8055.h index 3b42a1c..0645021 100644 --- a/src/k8055.h +++ b/src/k8055.h @@ -24,7 +24,20 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ + + Thanks to the following people who wrote the original version of `libk8055' + (http://libk8055.sourceforge.net/), without their useful comments this + library would not have been possible: + + 2005 by Sven Lindberg + + 2007 by Pjetur G. Hjaltason + Commenting, general rearrangement of code, bugfixes, + python interface with swig and simple k8055 python class + + The comments explaining the data packets and debounce time conversion + (in the source file) are from them. +*/ #ifndef K8055_H_ #define K8055_H_ @@ -50,6 +63,8 @@ enum k8055_error_code { K8055_ERROR_MEM = -12 /* memory allocation error */ }; +void k8055_debug(bool value); + /**Opens a K8055 device on the given port (i.e. address). * @return 0 on success * @return K8055_ERROR_INDEX if port is an invalid index diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..37a3b64 --- /dev/null +++ b/src/test.c @@ -0,0 +1,158 @@ +#include +#include +#include +#include "k8055.h" + +static int port = 0; + + +int test_all_analog(k8055_device* device) { + + for (int i = 0; i < 256; ++i) + if (k8055_set_all_analog(device, i, i) !=0 ) + return -1; + return 0; +} + +int test_all_digital(k8055_device* device) { + for (int i = 0; i < 256; ++i) + if (k8055_set_all_digital(device, i) !=0 ) + return -1; + return 0; +} + +int test_analog(k8055_device* device) { + struct timespec reqtime; + reqtime.tv_sec = 0; + reqtime.tv_nsec = 500000000; + + if (k8055_set_analog(device, 0, 0) != 0) return -1; + if (k8055_set_analog(device, 1, 0) != 0) return -1; + nanosleep(&reqtime, NULL); + if (k8055_set_analog(device, 0, 255) != 0) return -1; + if (k8055_set_analog(device, 1, 255) != 0) return -1; + nanosleep(&reqtime, NULL); + return 0; +} + +int test_digital(k8055_device* device) { + struct timespec reqtime; + reqtime.tv_sec = 0; + reqtime.tv_nsec = 500000000; + + for (int i = 0; i < 8; ++i) + if (k8055_set_digital(device, i, false) != 0) return -1; + nanosleep(&reqtime, NULL); + for (int i = 0; i < 8; ++i) + if (k8055_set_digital(device, i, true) != 0) return -1; + nanosleep(&reqtime, NULL); + return 0; +} + +int test_get_all_input(k8055_device* device) { + if (k8055_get_all_input(device, NULL, NULL, NULL, NULL, NULL, false) != 0) return -1; + if (k8055_get_all_input(device, NULL, NULL, NULL, NULL, NULL, true) != 0) return -1; + return 0; +} + +int test_get_all_output(k8055_device* device) { + unsigned int iseed = (unsigned int)time(NULL); + srand(iseed); + + + int a0 = rand() % 256; + int a1 = rand() % 256; + int d = rand() % 256; + + if (k8055_set_all_analog(device, a0, a1) != 0) return -1; + if (k8055_set_all_digital(device, d) != 0) return -1; + + int ga0; + int ga1; + int gd; + k8055_get_all_output(device, &gd, &ga0, &ga1, NULL, NULL); + + if ((a0 != ga0) || (a1 != ga1) || (d != gd)) return -1; + return 0; +} + +int run_test(const char* name, int (*f)(k8055_device*), k8055_device* device) { + puts(name); + int result = f(device); + if (result == 0) puts("= success ="); + else puts("= FAILED ="); + puts(""); + return result; +} + +int run_all() { + k8055_debug(true); + k8055_device* device = NULL; + + size_t n = 6; + char* names[] = { + "= write all analog =", + "= write all digital =", + "= write analog =", + "= write digital =", + "= read input =", + "= read output =" + }; + + int (*tests[])(k8055_device*) = { + test_all_analog, + test_all_digital, + test_analog, + test_digital, + test_get_all_input, + test_get_all_output + }; + + + + printf("= open k8055 on port %i =\n", port); + if (k8055_open_device(port, &device) == 0) { + puts("= success ="); + puts(""); + } else { + puts("= FAILED =\n"); + puts(""); + return -1; + } + + for (int j = 0; j < n; ++j) + run_test(names[j], tests[j], device); + + printf("= reopen k8055 on port %i =\n", port); + k8055_close_device(device); + if (k8055_open_device(port, &device) == 0) { + puts("= success ="); + puts(""); + } else { + puts("= FAILED =\n"); + puts(""); + return -1; + } + + for (int j = 0; j < n; ++j) + run_test(names[j], tests[j], device); + + + puts("turning everything off"); + k8055_set_all_analog(device, 0, 0); + k8055_set_all_digital(device, 0); + k8055_close_device(device); + + return 0; +} + +int main(int argc, char *argv[]) { + if (argc <= 1) port = 0; + else port = atoi(argv[1]); + + int r = run_all(); + puts(""); + if (r == 0) puts("all tests completed successfully"); + else puts("some tests FAILED"); + return r; +} -- cgit v1.2.3