From 32b8c601af560dc52b2c4f79fcd528e6be27b2e2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 27 Apr 2024 09:25:49 +1000 Subject: [PATCH 1/3] use fastcrc if available --- generator/mavcrc.py | 61 ++++++++++++++++++++++++++++++++++++++++++++- requirements.txt | 3 ++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/generator/mavcrc.py b/generator/mavcrc.py index bd605919d..cd6e9463f 100644 --- a/generator/mavcrc.py +++ b/generator/mavcrc.py @@ -7,8 +7,13 @@ import sys from builtins import object +try: + import fastcrc + mcrf4xx = fastcrc.crc16.mcrf4xx +except Exception: + mcrf4xx = None -class x25crc(object): +class x25crc_slow(object): """CRC-16/MCRF4XX - based on checksum.h from mavlink library""" def __init__(self, buf=None): @@ -39,3 +44,57 @@ def accumulate_str(self, buf): Provided for backwards compatibility. accumulate now also works on strings. """ return self.accumulate(buf) + +class x25crc_fast(object): + """CRC-16/MCRF4XX - based on checksum.h from mavlink library""" + def __init__(self, buf=None): + self.crc = 0xFFFF + if buf is not None: + self.accumulate(buf) + + def accumulate(self, buf): + """add in some more bytes (it also accepts strings)""" + if sys.version_info[0] == 2: + if type(buf) is str: + buf = bytearray(buf) + elif type(buf).__name__ == 'unicode': + # we can't use the identifier unicode in python3 + buf = bytearray(buf.encode()) + elif type(buf) is str: + buf = bytes(buf.encode()) + elif type(buf) is list: + buf = bytes(buf) + self.crc = mcrf4xx(buf, self.crc) + + def accumulate_str(self, buf): + """ + Provided for backwards compatibility. accumulate now also works on strings. + """ + return self.accumulate(buf) + +if mcrf4xx is not None: + x25crc = x25crc_fast +else: + x25crc = x25crc_slow + +if __name__ == "__main__": + import random, time + + for i in range(100): + nbytes = random.randint(1000,5000) + b = random.randbytes(nbytes) + + t1 = time.time() + slow = x25crc_slow() + t2 = time.time() + slow_t = t2 - t1 + + t1 = time.time() + c = x25crc() + t2 = time.time() + fast_t = t2 - t1 + + slow.accumulate(b) + c.accumulate(b) + assert slow.crc == c.crc + print("Speedup %.2f" % (slow_t/fast_t)) diff --git a/requirements.txt b/requirements.txt index 9591f7b7b..1dea9d17f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,8 @@ lxml>=3.6.0 future>=0.15.2 wheel>=0.37.1 setuptools>=42 +fastcrc # dev dependencies: pytest<=7.4.4 -syrupy; python_version>='3.6' \ No newline at end of file +syrupy; python_version>='3.6' From e3d761807340ee0df2a76d0c20207dac6dfdae63 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 27 Apr 2024 11:03:41 +1000 Subject: [PATCH 2/3] CI: drop python 3.5 support 3.5 was EOL in 2020, and doesn't support fastcrc --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e82480d04..7c60cf686 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false # don't cancel if a job from the matrix fails matrix: - python-version: ['3.5', '3.6', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] + python-version: ['3.6', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v3 From 2373dade5f01c4f4fae55e1a91129957856d601f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 27 Apr 2024 11:43:26 +1000 Subject: [PATCH 3/3] test: added parse_tlog for performance testing --- generator/C/test/posix/Makefile | 3 ++ generator/C/test/posix/parse_tlog.c | 59 +++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 generator/C/test/posix/parse_tlog.c diff --git a/generator/C/test/posix/Makefile b/generator/C/test/posix/Makefile index f1b993fcd..d0a05e988 100644 --- a/generator/C/test/posix/Makefile +++ b/generator/C/test/posix/Makefile @@ -50,3 +50,6 @@ testmav2.0_minimal: testmav.c sha256_test: sha256_test.c $(CC) $(CFLAGS) -I../../include_v2.0 -o $@ sha256_test.c + +parse_tlog: parse_tlog.c + $(CC) $(CFLAGS) -I../../include_v2.0 -I../../include_v2.0/ardupilotmega -o $@ parse_tlog.c diff --git a/generator/C/test/posix/parse_tlog.c b/generator/C/test/posix/parse_tlog.c new file mode 100644 index 000000000..160a4f367 --- /dev/null +++ b/generator/C/test/posix/parse_tlog.c @@ -0,0 +1,59 @@ +/* + parse a tlog, for performance testing + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAVLINK_USE_CONVENIENCE_FUNCTIONS +#define MAVLINK_USE_MESSAGE_INFO +#define MAVLINK_COMM_NUM_BUFFERS 2 + +// this trick allows us to make mavlink_message_t as small as possible +// for this dialect, which saves some memory +#include +#define MAVLINK_MAX_PAYLOAD_LEN MAVLINK_MAX_DIALECT_PAYLOAD_SIZE + +#include +static mavlink_system_t mavlink_system = {42,11,}; + +#define MAVLINK_ASSERT(x) assert(x) +static void comm_send_ch(mavlink_channel_t chan, uint8_t c) {} + +#include + +int main(int argc, const char *argv[]) +{ + if (argc < 2) { + printf("Usage: parse_tlog FILENAME\n"); + exit(1); + } + const char *filename = argv[1]; + int fd = open(filename, O_RDONLY); + if (fd == -1) { + perror(filename); + exit(1); + } + mavlink_channel_t chan = MAVLINK_COMM_0; + char c; + uint32_t msg_count = 0; + mavlink_message_t last_msg; + mavlink_status_t status; + + while (read(fd, &c, 1) == 1) { + if (mavlink_parse_char(chan, c, &last_msg, &status)) { + msg_count++; + } + } + printf("parsed %u messages\n", (unsigned)msg_count); + + return 0; +} +