diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-11-12 16:29:37 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-12-08 08:27:23 -0700 |
commit | d07ade8014628930057f5398fc26b06a527bb4d0 (patch) | |
tree | 492e5a416bd2d6a9d701dde323e7643f397b3f37 | |
parent | 957931e0f585b5132bf16e28b7eb3e68aec70d9a (diff) |
w5500: Add DEBUG logging
-rw-r--r-- | cmd/sbc_harness/config/config.h | 2 | ||||
-rw-r--r-- | libhw/w5500.c | 132 | ||||
-rw-r--r-- | libhw_generic/include/libhw/generic/net.h | 15 | ||||
-rw-r--r-- | libmisc/include/libmisc/log.h | 4 | ||||
-rw-r--r-- | libmisc/log.c | 266 |
5 files changed, 394 insertions, 25 deletions
diff --git a/cmd/sbc_harness/config/config.h b/cmd/sbc_harness/config/config.h index 6d2ea89..3f7a0bf 100644 --- a/cmd/sbc_harness/config/config.h +++ b/cmd/sbc_harness/config/config.h @@ -25,6 +25,8 @@ #define CONFIG_W5500_LOCAL_PORT_MIN 32768 #define CONFIG_W5500_LOCAL_PORT_MAX 60999 +#define CONFIG_W5500_DEBUG 1 /* bool */ + /* 9P *************************************************************************/ #define CONFIG_9P_PORT 564 diff --git a/libhw/w5500.c b/libhw/w5500.c index c1607f1..e675ae9 100644 --- a/libhw/w5500.c +++ b/libhw/w5500.c @@ -67,6 +67,8 @@ * SPDX-License-Identifier: MIT */ +#include <inttypes.h> /* for PRIu{n} */ + /* TODO: Write a <libhw/generic/gpio.h> to avoid w5500.c being * pico-sdk-specific. */ #include <hardware/gpio.h> /* pico-sdk:hardware_gpio */ @@ -77,7 +79,7 @@ #include <libhw/generic/alarmclock.h> /* for sleep_*() */ #define LOG_NAME W5500 -#include <libmisc/log.h> /* for errorf() */ +#include <libmisc/log.h> /* for errorf(), debugf(), const_byte_str() */ #define IMPLEMENTATION_FOR_LIBHW_W5500_H YES #include <libhw/w5500.h> @@ -88,26 +90,43 @@ #include "config.h" -/* These are the default values of the Linux kernel's - * net.ipv4.ip_local_port_range, so I figure they're probably good - * values to use. */ #ifndef CONFIG_W5500_LOCAL_PORT_MIN #error config.h must define CONFIG_W5500_LOCAL_PORT_MIN #endif - #ifndef CONFIG_W5500_LOCAL_PORT_MAX #error config.h must define CONFIG_W5500_LOCAL_PORT_MAX #endif - #ifndef CONFIG_W5500_NUM #error config.h must define CONFIG_W5500_NUM #endif +#ifndef CONFIG_W5500_DEBUG + #error config.h must define CONFIG_W5500_DEBUG +#endif /* C language *****************************************************************/ #define UNUSED(name) #define ARRAY_LEN(ary) (sizeof(ary)/sizeof((ary)[0])) +static const char *w5500_state_str(uint8_t state) { + switch (state) { + case STATE_CLOSED: return "STATE_CLOSED"; + case STATE_TCP_INIT: return "STATE_TCP_INIT"; + case STATE_TCP_LISTEN: return "STATE_TCP_LISTEN"; + case STATE_TCP_SYNSENT: return "STATE_TCP_SYNSENT"; + case STATE_TCP_SYNRECV: return "STATE_TCP_SYNRECV"; + case STATE_TCP_ESTABLISHED: return "STATE_TCP_ESTABLISHED"; + case STATE_TCP_FIN_WAIT: return "STATE_TCP_FIN_WAIT"; + case STATE_TCP_CLOSING: return "STATE_TCP_CLOSING"; + case STATE_TCP_TIME_WAIT: return "STATE_TCP_TIME_WAIT"; + case STATE_TCP_CLOSE_WAIT: return "STATE_TCP_CLOSE_WAIT"; + case STATE_TCP_LAST_ACK: return "STATE_TCP_LAST_ACK"; + case STATE_UDP: return "STATE_UDP"; + case STATE_MACRAW: return "STATE_MACRAW"; + default: return const_byte_str(state); + } +} + /* vtables ********************************************************************/ /* iface */ @@ -207,7 +226,10 @@ static COROUTINE w5500_irq_cr(void *_chip) { for (;;) { while (!gpio_get(chip->pin_intr)) { - if (w5500ll_read_common_reg(chip->spidev, chip_interrupt)) + debugf("w5500_irq_cr(): gpio low"); + + uint8_t chipintr = w5500ll_read_common_reg(chip->spidev, chip_interrupt); + if (chipintr) w5500ll_write_common_reg(chip->spidev, chip_interrupt, 0xFF); uint8_t sockmask = w5500ll_read_common_reg(chip->spidev, sock_interrupt); @@ -226,12 +248,18 @@ static COROUTINE w5500_irq_cr(void *_chip) { send_bits = sockintr & (SOCKINTR_SEND_OK|SOCKINTR_SEND_TIMEOUT), recv_bits = sockintr & (SOCKINTR_RECV_DAT|SOCKINTR_RECV_FIN); - if (listen_bits) + if (listen_bits) { + debugf("w5500_irq_cr(): signal sock[%"PRIu8"]->listen_sema", socknum); cr_sema_signal(&socket->listen_sema); - if (recv_bits) + } + if (recv_bits) { + debugf("w5500_irq_cr(): signal sock[%"PRIu8"]->read_sema", socknum); cr_sema_signal(&socket->read_sema); - if (send_bits) + } + if (send_bits) { + debugf("w5500_irq_cr(): signal sock[%"PRIu8"]->write_ch", socknum); _w5500_sockintr_ch_send(&socket->write_ch, send_bits); + } break; } @@ -239,6 +267,7 @@ static COROUTINE w5500_irq_cr(void *_chip) { } } cr_sema_wait(&chip->intr); + debugf("w5500_irq_cr(): sema signalled"); } cr_end(); @@ -296,6 +325,7 @@ static inline void w5500_socket_close(struct _w5500_socket *socket) { static struct w5500 *w5500_chips[CONFIG_W5500_NUM] = {0}; static void w5500_intrhandler(uint gpio, uint32_t UNUSED(event_mask)) { + debugf("w5500_intrhandler(): interrupt on pin %u", gpio); for (size_t i = 0; i < ARRAY_LEN(w5500_chips); i++) if (w5500_chips[i] && w5500_chips[i]->pin_intr == gpio) cr_sema_signal_from_intrhandler(&w5500_chips[i]->intr); @@ -328,8 +358,8 @@ void _w5500_init(struct w5500 *chip, .socknum = i, /* mutable */ .next_free = (i + 1 < 8) ? &chip->sockets[i+1] : NULL, - /* the rest of the mutable members get - * initialized to the zero values */ + /* The rest of the mutable members get + * initialized to the zero values. */ }; } @@ -361,7 +391,7 @@ void _w5500_init(struct w5500 *chip, /* chip methods ***************************************************************/ -static inline void w5500_post_reset(struct w5500 *chip) { +static void w5500_post_reset(struct w5500 *chip) { /* The W5500 does not have a built-in MAC address, we must * provide one. */ w5500ll_write_common_reg(chip->spidev, eth_addr, chip->hwaddr); @@ -426,7 +456,7 @@ static struct net_eth_addr w5500_if_hwaddr(implements_net_iface *_chip) { return chip->hwaddr; } -static void w5500_if_up(implements_net_iface *_chip, struct net_iface_config cfg) { +static void _w5500_if_up(implements_net_iface *_chip, struct net_iface_config cfg) { struct w5500 *chip = VCALL_SELF(struct w5500, implements_net_iface, _chip); assert(chip); @@ -435,8 +465,17 @@ static void w5500_if_up(implements_net_iface *_chip, struct net_iface_config cfg w5500ll_write_common_reg(chip->spidev, ip_addr, cfg.addr); } +static void w5500_if_up(implements_net_iface *_chip, struct net_iface_config cfg) { + debugf("if_up()"); + debugf(":: addr = "PRI_net_ip4_addr, ARG_net_ip4_addr(cfg.addr)); + debugf(":: gateway_addr = "PRI_net_ip4_addr, ARG_net_ip4_addr(cfg.gateway_addr)); + debugf(":: subnet_mask = "PRI_net_ip4_addr, ARG_net_ip4_addr(cfg.subnet_mask)); + _w5500_if_up(_chip, cfg); +} + static void w5500_if_down(implements_net_iface *_chip) { - w5500_if_up(_chip, (struct net_iface_config){0}); + debugf("if_down()"); + _w5500_if_up(_chip, (struct net_iface_config){0}); } static implements_net_stream_listener *w5500_if_tcp_listen(implements_net_iface *_chip, uint16_t local_port) { @@ -444,8 +483,11 @@ static implements_net_stream_listener *w5500_if_tcp_listen(implements_net_iface assert(chip); struct _w5500_socket *sock = w5500_alloc_socket(chip); - if (!sock) + if (!sock) { + debugf("tcp_listen() => no sock"); return NULL; + } + debugf("tcp_listen() => sock[%"PRIu8"]", sock->socknum); if (!local_port) local_port = w5500_alloc_local_port(chip); @@ -468,9 +510,12 @@ static implements_net_stream_conn *w5500_if_tcp_dial(implements_net_iface *_chip assert(port); struct _w5500_socket *socket = w5500_alloc_socket(chip); - if (!socket) + if (!socket) { + debugf("tcp_dial() => no sock"); return NULL; + } uint8_t socknum = socket->socknum; + debugf("tcp_dial() => sock[%"PRIu8"]", socknum); uint16_t local_port = w5500_alloc_local_port(chip); @@ -495,6 +540,7 @@ static implements_net_stream_conn *w5500_if_tcp_dial(implements_net_iface *_chip w5500_socket_cmd(socket, CMD_CONNECT); for (;;) { uint8_t state = w5500ll_read_sock_reg(chip->spidev, socknum, state); + debugf("tcp_dial(): state=%s", w5500_state_str(state)); switch (state) { case STATE_TCP_SYNSENT: cr_yield(); @@ -507,14 +553,17 @@ static implements_net_stream_conn *w5500_if_tcp_dial(implements_net_iface *_chip } } -implements_net_packet_conn *w5500_if_udp_conn(implements_net_iface *_chip, uint16_t local_port) { +static implements_net_packet_conn *w5500_if_udp_conn(implements_net_iface *_chip, uint16_t local_port) { struct w5500 *chip = VCALL_SELF(struct w5500, implements_net_iface, _chip); assert(chip); struct _w5500_socket *socket = w5500_alloc_socket(chip); - if (!socket) + if (!socket) { + debugf("udp_conn() => no sock"); return NULL; + } uint8_t socknum = socket->socknum; + debugf("udp_conn() => sock[%"PRIu8"]", socknum); if (!local_port) local_port = w5500_alloc_local_port(chip); @@ -541,8 +590,10 @@ static implements_net_stream_conn *w5500_tcplist_accept(implements_net_stream_li ASSERT_SELF(stream_listener, TCP); restart: - if (!socket->list_open) + if (!socket->list_open) { + debugf("tcp_listener.accept() => already closed"); return NULL; + } /* Mimics socket.c:socket(). */ w5500_socket_close(socket); @@ -556,6 +607,7 @@ static implements_net_stream_conn *w5500_tcplist_accept(implements_net_stream_li w5500_socket_cmd(socket, CMD_LISTEN); for (;;) { uint8_t state = w5500ll_read_sock_reg(chip->spidev, socknum, state); + debugf("tcp_listener.accept() => state=%s", w5500_state_str(state)); switch (state) { case STATE_TCP_LISTEN: case STATE_TCP_SYNRECV: @@ -574,6 +626,7 @@ static implements_net_stream_conn *w5500_tcplist_accept(implements_net_stream_li } static int w5500_tcplist_close(implements_net_stream_listener *_socket) { + debugf("tcp_listener.close()"); ASSERT_SELF(stream_listener, TCP); socket->list_open = false; @@ -584,6 +637,7 @@ static int w5500_tcplist_close(implements_net_stream_listener *_socket) { /* tcp_conn methods ***********************************************************/ static ssize_t w5500_tcp_write(implements_net_stream_conn *_socket, void *buf, size_t count) { + debugf("tcp_conn.write(%zu)", count); ASSERT_SELF(stream_conn, TCP); assert(buf); assert(count); @@ -610,11 +664,15 @@ static ssize_t w5500_tcp_write(implements_net_stream_conn *_socket, void *buf, s size_t done = 0; while (done < count) { - if (!socket->write_open) + if (!socket->write_open) { + debugf(" => soft closed"); return -NET_ECLOSED; + } uint8_t state = w5500ll_read_sock_reg(chip->spidev, socknum, state); - if (state != STATE_TCP_ESTABLISHED && state != STATE_TCP_CLOSE_WAIT) + if (state != STATE_TCP_ESTABLISHED && state != STATE_TCP_CLOSE_WAIT) { + debugf(" => hard closed"); return -NET_ECLOSED; + } uint16_t freesize = uint16be_unmarshal(w5500ll_read_sock_reg(chip->spidev, socknum, tx_free_size)); if (freesize < count-done && freesize < min_free_space) { @@ -634,9 +692,11 @@ static ssize_t w5500_tcp_write(implements_net_stream_conn *_socket, void *buf, s w5500_socket_cmd(socket, CMD_SEND); switch (_w5500_sockintr_ch_recv(&socket->write_ch)) { case SOCKINTR_SEND_OK: + debugf(" => sent %zu", freesize); done += freesize; break; case SOCKINTR_SEND_TIMEOUT: + debugf(" => ACK timeout"); return -NET_EACK_TIMEOUT; case SOCKINTR_SEND_OK|SOCKINTR_SEND_TIMEOUT: assert_notreached("send both OK and timed out?"); @@ -644,10 +704,12 @@ static ssize_t w5500_tcp_write(implements_net_stream_conn *_socket, void *buf, s assert_notreached("invalid write_ch bits"); } } + debugf(" => send finished"); return done; } static void w5500_tcp_set_read_deadline(implements_net_stream_conn *_socket, uint64_t ns) { + debugf("tcp_conn.set_read_deadline(%"PRIu64")", ns); ASSERT_SELF(stream_conn, TCP); socket->read_deadline_ns = ns; } @@ -658,6 +720,7 @@ static void w5500_tcp_alarm_handler(void *_arg) { } static ssize_t w5500_tcp_read(implements_net_stream_conn *_socket, void *buf, size_t count) { + debugf("tcp_conn.read()"); ASSERT_SELF(stream_conn, TCP); assert(buf); assert(count); @@ -674,10 +737,12 @@ static ssize_t w5500_tcp_read(implements_net_stream_conn *_socket, void *buf, si for (;;) { if (!socket->read_open) { VCALL(bootclock, del_trigger, &trigger); + debugf(" => soft closed"); return -NET_ECLOSED; } if (socket->read_deadline_ns && socket->read_deadline_ns <= VCALL(bootclock, get_time_ns)) { VCALL(bootclock, del_trigger, &trigger); + debugf(" => recv timeout"); return -NET_ERECV_TIMEOUT; } uint8_t state = w5500ll_read_sock_reg(chip->spidev, socknum, state); @@ -688,6 +753,7 @@ static ssize_t w5500_tcp_read(implements_net_stream_conn *_socket, void *buf, si break; /* OK */ default: VCALL(bootclock, del_trigger, &trigger); + debugf(" => hard closed"); return -NET_ECLOSED; } @@ -697,12 +763,14 @@ static ssize_t w5500_tcp_read(implements_net_stream_conn *_socket, void *buf, si break; if (state == STATE_TCP_CLOSE_WAIT) { VCALL(bootclock, del_trigger, &trigger); - return 0; /* EOF */ + debugf(" => EOF"); + return 0; } cr_sema_wait(&socket->read_sema); } assert(avail); + debugf(" => received %"PRIu16" bytes", avail); uint16_t ptr = uint16be_unmarshal(w5500ll_read_sock_reg(chip->spidev, socknum, rx_read_pointer)); /* Read the data. */ if ((size_t)avail > count) @@ -717,6 +785,7 @@ static ssize_t w5500_tcp_read(implements_net_stream_conn *_socket, void *buf, si } static int w5500_tcp_close(implements_net_stream_conn *_socket, bool rd, bool wr) { + debugf("tcp_conn.close(rd=%s, wr=%s)", rd ? "true" : "false", wr ? "true" : "false"); ASSERT_SELF(stream_conn, TCP); if (rd) @@ -748,18 +817,23 @@ static int w5500_tcp_close(implements_net_stream_conn *_socket, bool rd, bool wr static ssize_t w5500_udp_sendto(implements_net_packet_conn *_socket, void *buf, size_t count, struct net_ip4_addr node, uint16_t port) { + debugf("udp_conn.sendto()"); ASSERT_SELF(packet_conn, UDP); assert(buf); assert(count); uint16_t bufsize = ((uint16_t)w5500ll_read_sock_reg(chip->spidev, socknum, tx_buf_size))*1024; - if (count > bufsize) + if (count > bufsize) { + debugf(" => msg too large"); return -NET_EMSGSIZE; + } for (;;) { uint8_t state = w5500ll_read_sock_reg(chip->spidev, socknum, state); - if (state != STATE_UDP) + if (state != STATE_UDP) { + debugf(" => closed"); return -NET_ECLOSED; + } uint16_t freesize = uint16be_unmarshal(w5500ll_read_sock_reg(chip->spidev, socknum, tx_free_size)); if (freesize >= count) @@ -782,8 +856,10 @@ static ssize_t w5500_udp_sendto(implements_net_packet_conn *_socket, void *buf, switch (_w5500_sockintr_ch_recv(&socket->write_ch)) { case SOCKINTR_SEND_OK: + debugf(" => sent"); return count; case SOCKINTR_SEND_TIMEOUT: + debugf(" => ARP timeout"); return -NET_EARP_TIMEOUT; case SOCKINTR_SEND_OK|SOCKINTR_SEND_TIMEOUT: assert_notreached("send both OK and timed out?"); @@ -793,6 +869,7 @@ static ssize_t w5500_udp_sendto(implements_net_packet_conn *_socket, void *buf, } static void w5500_udp_set_read_deadline(implements_net_packet_conn *_socket, uint64_t ns) { + debugf("udp_conn.set_read_deadline(%"PRIu64")", ns); ASSERT_SELF(packet_conn, UDP); socket->read_deadline_ns = ns; } @@ -804,6 +881,7 @@ static void w5500_udp_alarm_handler(void *_arg) { static ssize_t w5500_udp_recvfrom(implements_net_packet_conn *_socket, void *buf, size_t count, struct net_ip4_addr *ret_node, uint16_t *ret_port) { + debugf("udp_conn.recvfrom()"); ASSERT_SELF(packet_conn, UDP); assert(buf); assert(count); @@ -820,11 +898,13 @@ static ssize_t w5500_udp_recvfrom(implements_net_packet_conn *_socket, void *buf for (;;) { if (socket->read_deadline_ns && socket->read_deadline_ns <= VCALL(bootclock, get_time_ns)) { VCALL(bootclock, del_trigger, &trigger); + debugf(" => recv timeout"); return -NET_ERECV_TIMEOUT; } uint8_t state = w5500ll_read_sock_reg(chip->spidev, socknum, state); if (state != STATE_UDP) { VCALL(bootclock, del_trigger, &trigger); + debugf(" => hard closed"); return -NET_ECLOSED; } @@ -851,6 +931,7 @@ static ssize_t w5500_udp_recvfrom(implements_net_packet_conn *_socket, void *buf if (ret_port) *ret_port = uint16be_decode(&hdr[4]); uint16_t len = uint16be_decode(&hdr[6]); + debugf(" => received %"PRIu16" bytes%s", len, len < avail-8 ? " (plus more messages)" : ""); /* Now read the actual data. */ if (count > len) count = len; @@ -864,6 +945,7 @@ static ssize_t w5500_udp_recvfrom(implements_net_packet_conn *_socket, void *buf } static int w5500_udp_close(implements_net_packet_conn *_socket) { + debugf("udp_conn.close()"); ASSERT_SELF(packet_conn, UDP); w5500_socket_close(socket); diff --git a/libhw_generic/include/libhw/generic/net.h b/libhw_generic/include/libhw/generic/net.h index 150d199..a016d51 100644 --- a/libhw_generic/include/libhw/generic/net.h +++ b/libhw_generic/include/libhw/generic/net.h @@ -7,6 +7,7 @@ #ifndef _LIBHW_GENERIC_NET_H_ #define _LIBHW_GENERIC_NET_H_ +#include <inttypes.h> /* for PRI{u,x}{n} */ #include <stdbool.h> /* for bool */ #include <stddef.h> /* for size_t */ #include <stdint.h> /* for uint{n}_t} */ @@ -31,10 +32,24 @@ struct net_ip4_addr { static const struct net_ip4_addr net_ip4_addr_broadcast = {{255, 255, 255, 255}}; static const struct net_ip4_addr net_ip4_addr_zero = {{0, 0, 0, 0}}; +#define PRI_net_ip4_addr "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8 +#define ARG_net_ip4_addr(addr) (addr).octets[0], \ + (addr).octets[1], \ + (addr).octets[2], \ + (addr).octets[3] + struct net_eth_addr { unsigned char octets[6]; }; +#define PRI_net_eth_addr "%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8":%02"PRIx8 +#define ARG_net_eth_addr(addr) (addr).octets[0], \ + (addr).octets[1], \ + (addr).octets[2], \ + (addr).octets[3], \ + (addr).octets[4], \ + (addr).octets[5] + /* Streams (e.g. TCP) *********************************************************/ struct net_stream_listener_vtable; diff --git a/libmisc/include/libmisc/log.h b/libmisc/include/libmisc/log.h index 37da20b..c1e4a05 100644 --- a/libmisc/include/libmisc/log.h +++ b/libmisc/include/libmisc/log.h @@ -7,6 +7,8 @@ #ifndef _LIBMISC_LOG_H_ #define _LIBMISC_LOG_H_ +#include <stdint.h> /* for uint8_t */ + #ifndef LOG_NAME #error "each compilation unit that includes <libmisc/log.h> must define LOG_NAME" #endif @@ -28,4 +30,6 @@ #define debugf(fmt, ...) do { if (_LOG_CAT3(CONFIG_, LOG_NAME, _DEBUG) && !_LOG_NDEBUG) \ _log_printf("debug: " _LOG_STR(LOG_NAME) ": " fmt "\n" __VA_OPT__(,) __VA_ARGS__); } while (0) +const char *const_byte_str(uint8_t b); + #endif /* _LIBMISC_LOG_H_ */ diff --git a/libmisc/log.c b/libmisc/log.c index a1ec10f..9bf5366 100644 --- a/libmisc/log.c +++ b/libmisc/log.c @@ -7,6 +7,8 @@ #include <stdio.h> /* for vprintf() */ #include <stdarg.h> /* for va_list, va_start(), va_end() */ +#include <libmisc/assert.h> + #define LOG_NAME #include <libmisc/log.h> @@ -17,3 +19,267 @@ int _log_printf(const char *format, ...) { va_end(va); return ret; } + +static const char *byte_strs[] = { + "0x00", + "0x01", + "0x02", + "0x03", + "0x04", + "0x05", + "0x06", + "0x07", + "0x08", + "0x09", + "0x0A", + "0x0B", + "0x0C", + "0x0D", + "0x0E", + "0x0F", + "0x10", + "0x11", + "0x12", + "0x13", + "0x14", + "0x15", + "0x16", + "0x17", + "0x18", + "0x19", + "0x1A", + "0x1B", + "0x1C", + "0x1D", + "0x1E", + "0x1F", + "0x20", + "0x21", + "0x22", + "0x23", + "0x24", + "0x25", + "0x26", + "0x27", + "0x28", + "0x29", + "0x2A", + "0x2B", + "0x2C", + "0x2D", + "0x2E", + "0x2F", + "0x30", + "0x31", + "0x32", + "0x33", + "0x34", + "0x35", + "0x36", + "0x37", + "0x38", + "0x39", + "0x3A", + "0x3B", + "0x3C", + "0x3D", + "0x3E", + "0x3F", + "0x40", + "0x41", + "0x42", + "0x43", + "0x44", + "0x45", + "0x46", + "0x47", + "0x48", + "0x49", + "0x4A", + "0x4B", + "0x4C", + "0x4D", + "0x4E", + "0x4F", + "0x50", + "0x51", + "0x52", + "0x53", + "0x54", + "0x55", + "0x56", + "0x57", + "0x58", + "0x59", + "0x5A", + "0x5B", + "0x5C", + "0x5D", + "0x5E", + "0x5F", + "0x60", + "0x61", + "0x62", + "0x63", + "0x64", + "0x65", + "0x66", + "0x67", + "0x68", + "0x69", + "0x6A", + "0x6B", + "0x6C", + "0x6D", + "0x6E", + "0x6F", + "0x70", + "0x71", + "0x72", + "0x73", + "0x74", + "0x75", + "0x76", + "0x77", + "0x78", + "0x79", + "0x7A", + "0x7B", + "0x7C", + "0x7D", + "0x7E", + "0x7F", + "0x80", + "0x81", + "0x82", + "0x83", + "0x84", + "0x85", + "0x86", + "0x87", + "0x88", + "0x89", + "0x8A", + "0x8B", + "0x8C", + "0x8D", + "0x8E", + "0x8F", + "0x90", + "0x91", + "0x92", + "0x93", + "0x94", + "0x95", + "0x96", + "0x97", + "0x98", + "0x99", + "0x9A", + "0x9B", + "0x9C", + "0x9D", + "0x9E", + "0x9F", + "0xA0", + "0xA1", + "0xA2", + "0xA3", + "0xA4", + "0xA5", + "0xA6", + "0xA7", + "0xA8", + "0xA9", + "0xAA", + "0xAB", + "0xAC", + "0xAD", + "0xAE", + "0xAF", + "0xB0", + "0xB1", + "0xB2", + "0xB3", + "0xB4", + "0xB5", + "0xB6", + "0xB7", + "0xB8", + "0xB9", + "0xBA", + "0xBB", + "0xBC", + "0xBD", + "0xBE", + "0xBF", + "0xC0", + "0xC1", + "0xC2", + "0xC3", + "0xC4", + "0xC5", + "0xC6", + "0xC7", + "0xC8", + "0xC9", + "0xCA", + "0xCB", + "0xCC", + "0xCD", + "0xCE", + "0xCF", + "0xD0", + "0xD1", + "0xD2", + "0xD3", + "0xD4", + "0xD5", + "0xD6", + "0xD7", + "0xD8", + "0xD9", + "0xDA", + "0xDB", + "0xDC", + "0xDD", + "0xDE", + "0xDF", + "0xE0", + "0xE1", + "0xE2", + "0xE3", + "0xE4", + "0xE5", + "0xE6", + "0xE7", + "0xE8", + "0xE9", + "0xEA", + "0xEB", + "0xEC", + "0xED", + "0xEE", + "0xEF", + "0xF0", + "0xF1", + "0xF2", + "0xF3", + "0xF4", + "0xF5", + "0xF6", + "0xF7", + "0xF8", + "0xF9", + "0xFA", + "0xFB", + "0xFC", + "0xFD", + "0xFE", + "0xFF", +}; +static_assert(sizeof(byte_strs)/sizeof(byte_strs[0]) == 0x100); + +const char *const_byte_str(uint8_t b) { + return byte_strs[b]; +} |