1 /*
2 * Copyright (c) 2022 Rodrigo Peixoto <rodrigopex@gmail.com>
3 * SPDX-License-Identifier: Apache-2.0
4 */
5 #include "messages.h"
6
7 #include <zephyr/fatal.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/logging/log.h>
10 #include <zephyr/sys/util_macro.h>
11 #include <zephyr/sys/atomic.h>
12 #include <zephyr/zbus/zbus.h>
13
14 #if defined(CONFIG_BOARD_NATIVE_POSIX)
15 #include "native_rtc.h"
16 #define GET_ARCH_TIME_NS() (native_rtc_gettime_us(RTC_CLOCK_PSEUDOHOSTREALTIME) * NSEC_PER_USEC)
17 #elif defined(CONFIG_ARCH_POSIX)
18 #error "This sample cannot be built for other POSIX arch boards than native_posix"
19 #else
20 #define GET_ARCH_TIME_NS() (k_cyc_to_ns_near64(sys_clock_cycle_get_32()))
21 #endif
22
23 LOG_MODULE_DECLARE(zbus, CONFIG_ZBUS_LOG_LEVEL);
24
25 #define CONSUMER_STACK_SIZE (CONFIG_IDLE_STACK_SIZE + CONFIG_BM_MESSAGE_SIZE)
26 #define PRODUCER_STACK_SIZE (CONFIG_MAIN_STACK_SIZE + CONFIG_BM_MESSAGE_SIZE)
27
28 ZBUS_CHAN_DEFINE(bm_channel, /* Name */
29 struct bm_msg, /* Message type */
30
31 NULL, /* Validator */
32 NULL, /* User data */
33 ZBUS_OBSERVERS_EMPTY, /* observers */
34 ZBUS_MSG_INIT(0) /* Initial value {0} */
35 );
36
37 #define BYTES_TO_BE_SENT (256LLU * 1024LLU)
38 atomic_t count;
39
producer_thread(void)40 static void producer_thread(void)
41 {
42 LOG_INF("Benchmark 1 to %d using %s to transmit with message size: %u bytes",
43 CONFIG_BM_ONE_TO,
44 IS_ENABLED(CONFIG_BM_LISTENERS)
45 ? "LISTENERS"
46 : (IS_ENABLED(CONFIG_BM_SUBSCRIBERS) ? "SUBSCRIBERS" : "MSG_SUBSCRIBERS"),
47 CONFIG_BM_MESSAGE_SIZE);
48
49 struct bm_msg msg = {{0}};
50
51 uint16_t message_size = CONFIG_BM_MESSAGE_SIZE;
52
53 memcpy(msg.bytes, &message_size, sizeof(message_size));
54
55 uint64_t start_ns = GET_ARCH_TIME_NS();
56
57 for (uint64_t internal_count = BYTES_TO_BE_SENT / CONFIG_BM_ONE_TO; internal_count > 0;
58 internal_count -= CONFIG_BM_MESSAGE_SIZE) {
59 zbus_chan_pub(&bm_channel, &msg, K_FOREVER);
60 }
61
62 uint64_t end_ns = GET_ARCH_TIME_NS();
63
64 uint64_t duration_ns = end_ns - start_ns;
65
66 if (duration_ns == 0) {
67 LOG_ERR("Something wrong. Duration is zero!\n");
68 k_oops();
69 }
70 uint64_t i = ((BYTES_TO_BE_SENT * NSEC_PER_SEC) / MB(1)) / duration_ns;
71 uint64_t f = ((BYTES_TO_BE_SENT * NSEC_PER_SEC * 100) / MB(1) / duration_ns) % 100;
72
73 LOG_INF("Bytes sent = %llu, received = %lu", BYTES_TO_BE_SENT, atomic_get(&count));
74 LOG_INF("Average data rate: %llu.%lluMB/s", i, f);
75 LOG_INF("Duration: %llu.%09llus", duration_ns / NSEC_PER_SEC, duration_ns % NSEC_PER_SEC);
76
77 printk("\n@%llu\n", duration_ns / 1000);
78 }
79
80 K_THREAD_DEFINE(producer_thread_id, PRODUCER_STACK_SIZE * 2, producer_thread, NULL, NULL, NULL, 5,
81 0, 0);
82