summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt13
-rw-r--r--Makefile10
-rw-r--r--cmd/sbc_harness/CMakeLists.txt6
-rw-r--r--cmd/sbc_harness/main.c12
-rw-r--r--cmd/sbc_harness/usb_keyboard.c5
-rw-r--r--cmd/sbc_harness/usb_keyboard.h2
-rw-r--r--cmd/srv9p/main.c4
-rw-r--r--lib9p/CMakeLists.txt3
-rw-r--r--lib9p/srv.c9
-rw-r--r--lib9p/types.c16
-rwxr-xr-xlib9p/types.gen8
-rw-r--r--libcr/coroutine.c4
-rw-r--r--libcr_ipc/CMakeLists.txt3
-rw-r--r--libcr_ipc/include/libcr_ipc/chan.h2
-rw-r--r--libcr_ipc/include/libcr_ipc/rpc.h94
-rw-r--r--libcr_ipc/include/libcr_ipc/sema.h15
-rw-r--r--libcr_ipc/sema.c34
-rw-r--r--libnetio/CMakeLists.txt3
-rw-r--r--libnetio/netio_posix.c6
-rw-r--r--libusb/CMakeLists.txt7
-rwxr-xr-xlibusb/include/libusb/tusb_helpers.h.gen8
-rw-r--r--libusb/include/libusb/usb_common.h2
-rw-r--r--libusb/usb_common.c4
23 files changed, 156 insertions, 114 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1c55776..f33b81b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,20 +3,19 @@
# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-Licence-Identifier: AGPL-3.0-or-later
-cmake_minimum_required(VERSION 3.13)
+cmake_minimum_required(VERSION 3.30)
-set(PICO_SDK_PATH "${CMAKE_SOURCE_DIR}/3rd-party/pico-sdk")
-include(pico_sdk_import.cmake)
+if (_UBUILD_USE_PICO_SDK)
+ set(PICO_SDK_PATH "${CMAKE_SOURCE_DIR}/3rd-party/pico-sdk")
+ include(pico_sdk_import.cmake)
+endif()
project(sbc_harness)
-pico_sdk_init()
-
add_subdirectory(libcr)
add_subdirectory(libcr_ipc)
add_subdirectory(libusb)
add_subdirectory(libnetio)
add_subdirectory(lib9p)
-add_subdirectory(cmd/sbc_harness)
-add_subdirectory(cmd/srv9p)
+add_subdirectory(cmd/${_UBUILD_CMD})
diff --git a/Makefile b/Makefile
index 6ae28e5..39f85ff 100644
--- a/Makefile
+++ b/Makefile
@@ -28,11 +28,15 @@ libusb/include/libusb/tusb_helpers.h 3rd-party/MS-LCID.pdf 3rd-party/MS-LCID.txt
################################################################################
-build: build/Makefile $(generate/files)
+commands := $(patsubst cmd/%/CMakeLists.txt,%,$(wildcard cmd/*/CMakeLists.txt))
+build: $(foreach c,$(commands),cmd/$c/build)
.PHONY: build
-build/Makefile:
- mkdir -p build && cd build && cmake ..
+cmd/%/build: build/%/Makefile $(generate/files)
+ $(MAKE) -C $(<D)
+.PHONY: cmd/%/build
+build/%/Makefile: cmd/%/CMakeLists.txt
+ mkdir -p $(@D) && cd $(@D) && cmake -DCMAKE_BUILD_TYPE=Debug -D_UBUILD_CMD=$* $(shell if grep -q pico_sdk_init $<; then echo ' -D_UBUILD_USE_PICO_SDK=1 '; fi) ../..
generate: $(generate/files)
.PHONY: generate
diff --git a/cmd/sbc_harness/CMakeLists.txt b/cmd/sbc_harness/CMakeLists.txt
index 34f6360..08fb226 100644
--- a/cmd/sbc_harness/CMakeLists.txt
+++ b/cmd/sbc_harness/CMakeLists.txt
@@ -3,6 +3,8 @@
# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-Licence-Identifier: AGPL-3.0-or-later
+pico_sdk_init()
+
add_executable(sbc_harness
main.c
usb_keyboard.c
@@ -10,9 +12,7 @@ add_executable(sbc_harness
target_include_directories(sbc_harness PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/config)
target_link_libraries(sbc_harness
pico_stdlib
- pico_unique_id
- tinyusb_device
- tinyusb_board
+
libusb
)
pico_enable_stdio_usb(sbc_harness 0)
diff --git a/cmd/sbc_harness/main.c b/cmd/sbc_harness/main.c
index 1fd9f8c..31ce30b 100644
--- a/cmd/sbc_harness/main.c
+++ b/cmd/sbc_harness/main.c
@@ -4,15 +4,12 @@
* SPDX-Licence-Identifier: AGPL-3.0-or-later
*/
-/* newlib */
#include <string.h> /* for strlen() */
-
-/* pico-sdk */
#include "pico/stdlib.h"
-/* local */
-#include "coroutine.h"
-#include "usb_common.h"
+#include <libcr/coroutine.h>
+#include <libusb/usb_common.h>
+
#include "usb_keyboard.h"
COROUTINE hello_world_cr(void *_chan) {
@@ -21,7 +18,8 @@ COROUTINE hello_world_cr(void *_chan) {
cr_begin();
for (size_t i = 0;; i = (i+1) % strlen(msg)) {
- cr_rpc_req(chan, NULL, msg[i]);
+ int result;
+ cr_rpc_req(chan, &result, (uint32_t)msg[i]);
}
cr_end();
diff --git a/cmd/sbc_harness/usb_keyboard.c b/cmd/sbc_harness/usb_keyboard.c
index 1989b35..3cf0bb3 100644
--- a/cmd/sbc_harness/usb_keyboard.c
+++ b/cmd/sbc_harness/usb_keyboard.c
@@ -6,8 +6,9 @@
#include "tusb.h"
-#include "tusb_helpers.h" /* for TUD_ENDPOINT_IN */
-#include "usb_common.h"
+#include <libusb/tusb_helpers.h> /* for TUD_ENDPOINT_IN */
+#include <libusb/usb_common.h>
+
#include "usb_keyboard.h"
/**
diff --git a/cmd/sbc_harness/usb_keyboard.h b/cmd/sbc_harness/usb_keyboard.h
index 6b65360..8eba062 100644
--- a/cmd/sbc_harness/usb_keyboard.h
+++ b/cmd/sbc_harness/usb_keyboard.h
@@ -7,7 +7,7 @@
#ifndef _USB_KEYBOARD_H_
#define _USB_KEYBOARD_H_
-#include "coroutine_rpc.h"
+#include <libcr_ipc/rpc.h>
typedef cr_rpc_t(uint32_t, int) usb_keyboard_rpc_t;
diff --git a/cmd/srv9p/main.c b/cmd/srv9p/main.c
index 822a9ea..d63c5fb 100644
--- a/cmd/srv9p/main.c
+++ b/cmd/srv9p/main.c
@@ -1,8 +1,8 @@
#include <error.h>
#include <stdio.h>
-#include "coroutine.h"
-#include "net9p.h"
+#include <libcr/coroutine.h>
+#include <lib9p/srv.h>
int main() {
int sock = netio_listen(9000);
diff --git a/lib9p/CMakeLists.txt b/lib9p/CMakeLists.txt
index af73ba9..cd3156c 100644
--- a/lib9p/CMakeLists.txt
+++ b/lib9p/CMakeLists.txt
@@ -10,4 +10,7 @@ target_sources(lib9p INTERFACE
9p.c
srv.c
)
+target_link_libraries(lib9p INTERFACE
+ libcr_ipc
+)
set_source_files_properties(types.c PROPERTIES COMPILE_FLAGS -O3)
diff --git a/lib9p/srv.c b/lib9p/srv.c
index 59326c9..c6558d6 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -1,10 +1,11 @@
#include <assert.h>
-#include "coroutine.h"
-#include "netio.h"
-#include "9p/9p.h"
+#include <libcr/coroutine.h>
+#include <libcr_ipc/chan.h>
+#include <libnetio/netio.h>
-#include "9p/internal.h"
+#include <lib9p/9p.h>
+#include "internal.h"
struct p9_srvconn {
/* immutable */
diff --git a/lib9p/types.c b/lib9p/types.c
index c006d69..deceb4e 100644
--- a/lib9p/types.c
+++ b/lib9p/types.c
@@ -786,7 +786,7 @@ static bool marshal_Rswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rswrite *
/* vtables ********************************************************************/
struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = {
- [LIB9P_VER_UNINITIALIZED] = {
+ [LIB9P_VER_UNINITIALIZED] = { .msgs = {
[LIB9P_TYP_Tversion] = {
r.unmarshal_basesize = sizeof(struct lib9p_msg_Tversion),
r.unmarshal_extrasize = checksize_Tversion,
@@ -799,8 +799,8 @@ struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = {
r.unmarshal = unmarshal_Rversion,
r.marshal = (_marshal_fn_t)marshal_Rversion,
},
- },
- [LIB9P_VER_9P2000] = {
+ }},
+ [LIB9P_VER_9P2000] = { .msgs = {
[LIB9P_TYP_Tversion] = {
r.unmarshal_basesize = sizeof(struct lib9p_msg_Tversion),
r.unmarshal_extrasize = checksize_Tversion,
@@ -963,8 +963,8 @@ struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = {
r.unmarshal = unmarshal_Rwstat,
r.marshal = (_marshal_fn_t)marshal_Rwstat,
},
- },
- [LIB9P_VER_9P2000_e] = {
+ }},
+ [LIB9P_VER_9P2000_e] = { .msgs = {
[LIB9P_TYP_Tversion] = {
r.unmarshal_basesize = sizeof(struct lib9p_msg_Tversion),
r.unmarshal_extrasize = checksize_Tversion,
@@ -1163,8 +1163,8 @@ struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = {
r.unmarshal = unmarshal_Rswrite,
r.marshal = (_marshal_fn_t)marshal_Rswrite,
},
- },
- [LIB9P_VER_9P2000_u] = {
+ }},
+ [LIB9P_VER_9P2000_u] = { .msgs = {
[LIB9P_TYP_Tversion] = {
r.unmarshal_basesize = sizeof(struct lib9p_msg_Tversion),
r.unmarshal_extrasize = checksize_Tversion,
@@ -1327,5 +1327,5 @@ struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = {
r.unmarshal = unmarshal_Rwstat,
r.marshal = (_marshal_fn_t)marshal_Rwstat,
},
- },
+ }},
};
diff --git a/lib9p/types.gen b/lib9p/types.gen
index 5eee551..0de5068 100755
--- a/lib9p/types.gen
+++ b/lib9p/types.gen
@@ -586,18 +586,18 @@ static inline bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) {
/* vtables ********************************************************************/
struct _vtable_version _{idprefix}vtables[LIB9P_VER_NUM] = {{
- [{idprefix.upper()}VER_UNINITIALIZED] = {{
+ [{idprefix.upper()}VER_UNINITIALIZED] = {{ .msgs = {{
{msg_entry(next(msg for msg in structs if msg.name == 'Tversion'))},
{msg_entry(next(msg for msg in structs if msg.name == 'Rversion'))},
- }},
+ }}}},
"""
for ver in sorted(versions):
- ret += f"\t[{c_ver(idprefix, ver)}] = {{\n"
+ ret += f"\t[{c_ver(idprefix, ver)}] = {{ .msgs = {{\n"
for msg in structs:
if ver not in msg.msgver:
continue
ret += msg_entry(msg) + ",\n"
- ret += "\t},\n"
+ ret += "\t}},\n"
ret += "};\n"
############################################################################
diff --git a/libcr/coroutine.c b/libcr/coroutine.c
index 34a96b6..0920f23 100644
--- a/libcr/coroutine.c
+++ b/libcr/coroutine.c
@@ -357,11 +357,11 @@ void cr_yield(void) {
void cr_pause_and_yield(void) {
assert_cid_state(coroutine_running, == CR_RUNNING);
- if (coroutine_table[cid-1].sig_unpause)
+ if (coroutine_table[coroutine_running-1].sig_unpause)
_cr_transition(CR_RUNNABLE);
else
_cr_transition(CR_PAUSED);
- coroutine_table[cid-1].sig_unpause = false;
+ coroutine_table[coroutine_running-1].sig_unpause = false;
}
void cr_exit(void) {
diff --git a/libcr_ipc/CMakeLists.txt b/libcr_ipc/CMakeLists.txt
index b794908..3388fcd 100644
--- a/libcr_ipc/CMakeLists.txt
+++ b/libcr_ipc/CMakeLists.txt
@@ -8,3 +8,6 @@ target_include_directories(libcr_ipc SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/
target_sources(libcr_ipc INTERFACE
sema.c
)
+target_link_libraries(libcr_ipc INTERFACE
+ libcr
+)
diff --git a/libcr_ipc/include/libcr_ipc/chan.h b/libcr_ipc/include/libcr_ipc/chan.h
index a3621a6..66ea1c4 100644
--- a/libcr_ipc/include/libcr_ipc/chan.h
+++ b/libcr_ipc/include/libcr_ipc/chan.h
@@ -14,7 +14,7 @@
#include <assert.h>
-#include "coroutine.h"
+#include <libcr/coroutine.h>
/**
* cr_chan_t(val_t) returns the type definition for a channel on
diff --git a/libcr_ipc/include/libcr_ipc/rpc.h b/libcr_ipc/include/libcr_ipc/rpc.h
index 11d40d7..3c42f34 100644
--- a/libcr_ipc/include/libcr_ipc/rpc.h
+++ b/libcr_ipc/include/libcr_ipc/rpc.h
@@ -13,11 +13,11 @@
#include <assert.h>
-#include "coroutine.h"
+#include <libcr/coroutine.h>
/**
* cr_rpc_t(req_t, resp_t) returns the type definition for a
- * rcp-channel on which the requester submits a value of type `req_t`
+ * rpc-channel on which the requester submits a value of type `req_t`
* and the responder responds with a value of type `resp_t`.
*
* There may be multiple concurrent requesters, but only one
@@ -31,6 +31,10 @@
resp_t *resp_p; \
}
+#define _cr_rpc_static_assert_sametype(a, b, msg) \
+ static_assert(_Generic(a, typeof(b): 1, default: 0), msg)
+#define _cr_rpc_str(a) #a
+
/* These "functions" are preprocessor macros instead of real C
* functions so that the compiler can do type-checking instead of
* having these functions take `void*`. */
@@ -42,29 +46,38 @@
* Blocking: Always; until the responder has called both
* cr_rpc_recv_req() and cr_rpc_send_resp().
*/
-#define cr_rpc_req(ch, _resp_p, _req) do { \
- cid_t next = 0; \
- if ((ch)->requester) { \
- *((ch)->tail_requester = cr_getcid(); \
- (ch)->tail_requester = &next; \
- cr_pause_and_yield(); \
- } else { \
- (ch)->requester = cr_getcid(); \
- (ch)->tail_requester = &next; \
- } \
- assert((ch)->requester == cr_getcid()); \
- (ch)->req_p = &(_req); \
- (ch)->resp_p = (_resp_p; \
- if ((ch)->responder != 0) \
- cr_unpause((ch)->responder); \
- cr_pause_and_yield(); \
- if (next) { \
- (ch)->requester = next; \
- cr_unpause(next); \
- } else { \
- (ch)->requester = 0; \
- (ch)->tail_requester = NULL; \
- }
+#define cr_rpc_req(ch, _resp_p, _req) do { \
+ typeof(_req) _req_lvalue = _req; \
+ _cr_rpc_static_assert_sametype(_resp_p, (ch)->resp_p, \
+ "wrong resp_p type for rpc chan: " \
+ _cr_rpc_str(_resp_p)); \
+ _cr_rpc_static_assert_sametype(&_req_lvalue, (ch)->req_p, \
+ "wrong req type for rpc chan: " \
+ _cr_rpc_str(_req)); \
+ assert(ch); \
+ assert(_resp_p); \
+ cid_t next = 0; \
+ if ((ch)->requester) { \
+ *((ch)->tail_requester) = cr_getcid(); \
+ (ch)->tail_requester = &next; \
+ cr_pause_and_yield(); \
+ } else { \
+ (ch)->requester = cr_getcid(); \
+ (ch)->tail_requester = &next; \
+ } \
+ assert((ch)->requester == cr_getcid()); \
+ (ch)->req_p = &_req_lvalue; \
+ (ch)->resp_p = (_resp_p); \
+ if ((ch)->responder != 0) \
+ cr_unpause((ch)->responder); \
+ cr_pause_and_yield(); \
+ if (next) { \
+ (ch)->requester = next; \
+ cr_unpause(next); \
+ } else { \
+ (ch)->requester = 0; \
+ (ch)->tail_requester = NULL; \
+ } \
} while (0)
/**
@@ -84,12 +97,17 @@
*
* Blocking: Maybe.
*/
-#define cr_rpc_recv_req(ch, _req_p) do { \
- (ch)->responder = cr_getcid(); \
- if ((ch)->requester == 0) \
- cr_pause_and_yield(); \
- *(_req_p) = *((ch)->req_p); \
- (ch)->req_p = NULL; \
+#define cr_rpc_recv_req(ch, _req_p) do { \
+ _cr_rpc_static_assert_sametype(_req_p, (ch)->req_p, \
+ "wrong req_p type for rpc chan: " \
+ _cr_rpc_str(_req_p)); \
+ assert(ch); \
+ assert(_req_p); \
+ (ch)->responder = cr_getcid(); \
+ if ((ch)->requester == 0) \
+ cr_pause_and_yield(); \
+ *(_req_p) = *((ch)->req_p); \
+ (ch)->req_p = NULL; \
} while (0)
/**
@@ -98,11 +116,15 @@
*
* Blocking: Never.
*/
-#define cr_rpc_send_resp(ch, _resp) do { \
- (ch)->responder = 0; \
- *((ch)->resp_p) = (_resp); \
- (ch)->resp_p = NULL; \
- cr_unpause((ch)->requester); \
+#define cr_rpc_send_resp(ch, _resp) do { \
+ _cr_rpc_static_assert_sametype(_resp, *(ch)->resp_p, \
+ "wrong resp type for rpc chan: " \
+ _cr_rpc_str(_reps)); \
+ assert(ch); \
+ (ch)->responder = 0; \
+ *((ch)->resp_p) = (_resp); \
+ (ch)->resp_p = NULL; \
+ cr_unpause((ch)->requester); \
} while (0)
#endif /* _COROUTINE_RPC_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/sema.h b/libcr_ipc/include/libcr_ipc/sema.h
index 57d5855..a2a176d 100644
--- a/libcr_ipc/include/libcr_ipc/sema.h
+++ b/libcr_ipc/include/libcr_ipc/sema.h
@@ -7,12 +7,25 @@
#ifndef _COROUTINE_SEMA_H_
#define _COROUTINE_SEMA_H_
+struct _cr_sema_cid_list {
+ cid_t val;
+ struct _cr_sema_cid_list *next;
+};
+
/**
* A cr_sema_t is a fair unbounded[1] counting semaphore.
*
* [1]: Well, INT_MAX
*/
-typedef struct sema_t cr_sema_t;
+typedef volatile struct {
+ int cnt;
+
+ struct _cr_sema_cid_list *head, **tail;
+ /* locked indicates that a call from within a coroutine is is
+ * messing with ->{head,tail}, so a signal handler can't read
+ * it. */
+ bool locked;
+} cr_sema_t;
/**
* Increment the semaphore,
diff --git a/libcr_ipc/sema.c b/libcr_ipc/sema.c
index a8b5ec4..5f489aa 100644
--- a/libcr_ipc/sema.c
+++ b/libcr_ipc/sema.c
@@ -6,27 +6,11 @@
#include <assert.h>
-#include "coroutine_sema.h"
-
-struct cid_list {
- cid_t val;
- struct cid_list *next;
-};
-
-/* head->next->next->tail */
-
-struct _cr_sema {
- int cnt;
-
- struct cid_list *head, **tail;
- /* locked indicates that a call from within a coroutine is is
- * messing with ->{head,tail}, so a signal handler can't read
- * it. */
- bool locked;
-};
+#include <libcr/coroutine.h>
+#include <libcr_ipc/sema.h>
/** Drain the sema->{head,tail} list. Returns true if cr_getcid() was drained. */
-static inline bool drain(volatile cr_sema_t *sema) {
+static inline bool drain(cr_sema_t *sema) {
assert(!sema->locked);
cid_t self = cr_getcid();
@@ -59,21 +43,21 @@ static inline bool drain(volatile cr_sema_t *sema) {
/* If there are still coroutines in sema->head, check
* that sema->cnt wasn't incremented between `if
* (!sema->cnt)` and `sema->locked = false`. */
- } while (state == DRAINED_SOME && cnt);
+ } while (state == DRAINED_SOME && sema->cnt);
/* If state == DRAINED_SELF, then we better have been the last
* item in the list! */
assert(state != DRAINED_SELF || !sema->head);
return state == DRAINED_SELF;
}
-void cr_sema_signal(volatile cr_sema_t *sema) {
+void cr_sema_signal(cr_sema_t *sema) {
sema->cnt++;
if (!sema->locked)
- drain();
+ drain(sema);
}
-void cr_sema_wait(volatile cr_sema_t *sema) {
- struct cid_list self = {
+void cr_sema_wait(cr_sema_t *sema) {
+ struct _cr_sema_cid_list self = {
.val = cr_getcid(),
.next = NULL,
};
@@ -86,7 +70,7 @@ void cr_sema_wait(volatile cr_sema_t *sema) {
sema->tail = &(self.next);
sema->locked = false;
- if (drain())
+ if (drain(sema))
/* DRAINED_SELF: (1) No need to pause+yield, (2) we
* better have been the last item in the list! */
assert(!self.next);
diff --git a/libnetio/CMakeLists.txt b/libnetio/CMakeLists.txt
index 226a2e5..fcfecfd 100644
--- a/libnetio/CMakeLists.txt
+++ b/libnetio/CMakeLists.txt
@@ -7,4 +7,7 @@ add_library(libnetio INTERFACE)
target_sources(libnetio INTERFACE
netio_posix.c
)
+target_link_libraries(libnetio INTERFACE
+ libcr_ipc
+)
target_include_directories(libnetio SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
diff --git a/libnetio/netio_posix.c b/libnetio/netio_posix.c
index 46851f7..133b226 100644
--- a/libnetio/netio_posix.c
+++ b/libnetio/netio_posix.c
@@ -16,9 +16,9 @@
# include <fcntl.h> /* for fcntl(), F_SETFL, O_ASYNC, F_SETSIG */
#endif
-#include "netio.h"
-#include "coroutine.h"
-#include "coroutine_sema.h"
+#include <libnetio/netio.h>
+#include <libcr/coroutine.h>
+#include <libcr_ipc/sema.h>
/* I found the following post to be very helpful when writing this:
* http://davmac.org/davpage/linux/async-io.html */
diff --git a/libusb/CMakeLists.txt b/libusb/CMakeLists.txt
index e1a9284..c232868 100644
--- a/libusb/CMakeLists.txt
+++ b/libusb/CMakeLists.txt
@@ -8,3 +8,10 @@ target_include_directories(libusb SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/inc
target_sources(libusb INTERFACE
usb_common.c
)
+target_link_libraries(libusb INTERFACE
+ pico_unique_id
+ tinyusb_device
+ tinyusb_board
+
+ libcr_ipc
+)
diff --git a/libusb/include/libusb/tusb_helpers.h.gen b/libusb/include/libusb/tusb_helpers.h.gen
index 9b917da..82e15ba 100755
--- a/libusb/include/libusb/tusb_helpers.h.gen
+++ b/libusb/include/libusb/tusb_helpers.h.gen
@@ -63,8 +63,12 @@ cat <<'EOT'
* to sort their list of by most-significant-byte was a poor editorial choice.
*/
EOT
-[ -f 3rd-party/MS-LCID.pdf ] || wget -O 3rd-party/MS-LCID.pdf 'https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-LCID/%5bMS-LCID%5d.pdf'
-[ -f 3rd-party/MS-LCID.txt ] || pdftotext -layout 3rd-party/MS-LCID.pdf
+if [[ ! -f 3rd-party/MS-LCID.pdf || 3rd-party/MS-LCID.pdf -ot $0 ]]; then
+ wget --no-use-server-timestamps -O 3rd-party/MS-LCID.pdf 'https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-LCID/%5bMS-LCID%5d.pdf'
+fi
+if [[ ! -f 3rd-party/MS-LCID.txt || 3rd-party/MS-LCID.txt -ot 3rd-party/MS-LCID.txt ]]; then
+ pdftotext -layout 3rd-party/MS-LCID.pdf
+fi
<3rd-party/MS-LCID.txt \
grep -E '^\s*0x[0-9A-F]{4}\s+[a-z]' | sed 's/,.*//' | grep -v reserved | # find the lines we're interested in
sed -E 's/^\s*0x(..)(..)\s+(\S.*)/\2 \1 \3/p' | tr '[:lower:]-' '[:upper:]_' | # format them as 'PRIhex SUBhex UPPER_STR'
diff --git a/libusb/include/libusb/usb_common.h b/libusb/include/libusb/usb_common.h
index 3b45246..33308d2 100644
--- a/libusb/include/libusb/usb_common.h
+++ b/libusb/include/libusb/usb_common.h
@@ -7,7 +7,7 @@
#ifndef _USB_COMMON_H_
#define _USB_COMMON_H_
-#include "coroutine.h"
+#include <libcr/coroutine.h>
/* Strings ********************************************************************/
diff --git a/libusb/usb_common.c b/libusb/usb_common.c
index f10ace8..5485d71 100644
--- a/libusb/usb_common.c
+++ b/libusb/usb_common.c
@@ -11,8 +11,8 @@
#include "bsp/board_api.h" /* for board_init(), board_init_after_usb(), board_usb_get_serial(TinyUSB) */
#include "tusb.h" /* for various tusb_*_t types */
-#include "tusb_helpers.h" /* for LANGID_*, TU_UTF16() */
-#include "usb_common.h"
+#include <libusb/tusb_helpers.h> /* for LANGID_*, TU_UTF16() */
+#include <libusb/usb_common.h>
/* Strings ********************************************************************/