summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------3rd-party/pico-sdk0
-rw-r--r--CMakeLists.txt6
-rw-r--r--GNUmakefile8
-rw-r--r--README.md34
-rwxr-xr-xbuild-aux/lint-bin36
-rw-r--r--libhw/rp2040_include/libhw/rp2040_hwspi.h5
-rw-r--r--libmisc/include/libmisc/macro.h8
-rw-r--r--libmisc/include/libmisc/private.h7
-rw-r--r--libmisc/tests/test_macro.c25
9 files changed, 96 insertions, 33 deletions
diff --git a/3rd-party/pico-sdk b/3rd-party/pico-sdk
-Subproject 0e28a1b3cf28296a40f9c8c42d6340bdd7ebb30
+Subproject 1c00d64a4e0fdf948494c9aaf4d257b5739796a
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b90d000..c6c7068 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,13 +43,13 @@ function(target_embed_sources arg_compile_target arg_link_target arg_hdrname)
set(embed_objs)
foreach(embed_src IN LISTS ARGN)
add_custom_command(
- OUTPUT "${embed_src}.obj"
+ OUTPUT "${embed_src}.o"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMAND mkdir -p -- "$<PATH:GET_PARENT_PATH,${CMAKE_CURRENT_BINARY_DIR}/${embed_src}>" &&
- ${CMAKE_LINKER} -r -b binary -o "${CMAKE_CURRENT_BINARY_DIR}/${embed_src}.obj" "${embed_src}"
+ ${CMAKE_LINKER} -r -b binary -o "${CMAKE_CURRENT_BINARY_DIR}/${embed_src}.o" "${embed_src}"
DEPENDS "${embed_src}"
)
- list(APPEND embed_objs "${embed_src}.obj")
+ list(APPEND embed_objs "${embed_src}.o")
endforeach()
set_source_files_properties("${embed_objs}" PROPERTIES
EXTERNAL_OBJECT true
diff --git a/GNUmakefile b/GNUmakefile
index 5f49647..0913aec 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -81,7 +81,7 @@ $(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/Makefile)): buil
mkdir -p $(@D) && cd $(@D) && cmake -DPICO_PLATFORM=$(firstword $(subst -, ,$*)) -DCMAKE_BUILD_TYPE=$(lastword $(subst -, ,$*)) ../..
$(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/build)): build/%/build: build/%/Makefile generate
- $(MAKE) -C $(<D) INNER=t
+ $(MAKE) -C $(<D)
.PHONY: $(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/build))
check: build
@@ -89,7 +89,7 @@ check: build
.PHONY: check
$(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/check)): build/%/check: build/%/Makefile
- CTEST_OUTPUT_ON_FAILURE=1 $(MAKE) -C $(<D) INNER=t test
+ CTEST_OUTPUT_ON_FAILURE=1 $(MAKE) -C $(<D) test
.PHONY: $(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/check))
# `lint` and `format` ##########################################################
@@ -104,7 +104,9 @@ build-aux/venv: build-aux/requirements.txt
# `lint` ###########
lint:
- $(MAKE) -k INNER=t $(patsubst sources_%,lint/%,$(filter sources_%,$(.VARIABLES)))
+ $(MAKE) -k INNER=t $(patsubst sources_%,lint/%,$(filter sources_%,$(.VARIABLES))) lint/bin
+lint/bin: build build-aux/lint-bin
+ ./build-aux/lint-bin $(foreach t,$(build_types),build/rp2040-$t/cmd/sbc_harness/sbc_harness.elf)
lint/sh lint/bash: lint/%:
shellcheck $(sources_$*)
lint/python3: lint/%: build-aux/venv
diff --git a/README.md b/README.md
index 0e4b280..de909d3 100644
--- a/README.md
+++ b/README.md
@@ -18,15 +18,29 @@ At the time of this writing, on Parabola GNU/Linux-libre that means:
- arm-none-eabi-binutils 2.42-1
- arm-none-eabi-gcc 14.1.0-1
- arm-none-eabi-newlib 4.4.0.20231231-1
- - picotool 2.0.0-2
+ - picotool 2.1.1-1
Then, simply run `make`. This will create
-`build/rp2040-*/cmd/sbc_harness/sbc_harness.{bin,uf2,elf}` files. The
-`.bin` file is the raw firmware image; the `.uf2` file is that wrapped
-into a [USB Flashing Format (UF2)](https://github.com/microsoft/uf2)
-container that can be used with the bootrom flasher (yes, the
-`.uf2` is expected to be about twice the size of the `.bin`); the
-`.elf` is the firmware image plus debugger symbols.
+`build/rp2040-*/cmd/sbc_harness/sbc_harness.{elf,bin,hex,uf2}` files:
+
+ - The `.elf` is the firmware image plus debugger symbols and
+ relocation data.
+ - The `.bin` file is the raw firmware image (`objcopy -Obinary
+ INFILE.elf OUTFILE.bin`).
+ - The `.hex` file is the raw firmware image, encoded in the [Intel
+ HEX](https://archive.org/details/IntelHEXStandard) format (`objcopy
+ -Oihex INFILE.elf OUTFILE.hex`). Note that unlike the `.bin`, the
+ `.hex` may contain gaps/holes; holes are filled with 0x00-bytes in
+ the `.bin`, but tools for working with the `.hex` may fill them
+ with other data, causing minor differences when comparing the
+ `.bin` and `.hex`. (Yes, the `.hex` is expected to be about 2.8
+ times the size of the `.bin`; twice for being ASCII-encoded hex,
+ plus another 13 bytes overhead for every 16 bytes of input.)
+ - The `.uf2` file is the `.bin` wrapped into a [USB Flashing Format
+ (UF2)](https://github.com/microsoft/uf2) container that can be used
+ with the bootrom flasher. (Yes, the `.uf2` is expected to be about
+ twice the size of the `.bin`; each 128-byte block of input is
+ wrapped in a 256-byte UF2 block.)
There are several ways of putting this firmware file onto the harness:
@@ -55,9 +69,7 @@ There are several ways of putting this firmware file onto the harness:
The harness uses DHCP to acquire an IPv4 address, then serves the 9P
protocol over TCP:
- - TCP port: 564 (9P does not have a standard TCP port number, but
- this is the default port number used by most 9P-over-TCP clients,
- including the Linux kernel's v9fs driver).
+ - TCP port: 564
- Supported protocol versions:
- `9P2000` (base protocol): Yes
- `9P2000.u` (Unix extension): Yes, with Linux kernel
@@ -82,7 +94,7 @@ library for your programming language of choice.
Some notes on choosing a client:
- On x86-32, the Linux kernel v9fs driver is known to drop entries
- from directory listings; I advise using 9pfuse instead of you want
+ from directory listings; I advise using 9pfuse instead if you want
to mount it on 32-bit systems.
- I generally like mounting it as a real filesystem, but this means
that you only get errno errors, and the more-helpful error strings
diff --git a/build-aux/lint-bin b/build-aux/lint-bin
index 2fe8e4b..ffc2a12 100755
--- a/build-aux/lint-bin
+++ b/build-aux/lint-bin
@@ -5,7 +5,22 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
set -euE -o pipefail
+shopt -s extglob
+# There are several exisi files we can use:
+#
+# Binaries:
+# - ${elf} : firmware image with debug symbols and relocationd data
+# - ${elf%.elf}.bin : raw firmware image
+# - ${elf%.elf}.hex : .bin as Intel HEX
+# - ${elf%.elf}.uf2 : .bin as USB Flashing Format (UF2)
+#
+# Textual info:
+# - ${elf%.elf}.dis : `objdump --section-headers ${elf}; objdump --disassemble ${elf}; picotool coprodis --quiet ${elf}`
+# - ${elf}.map : `ld --print-map` info
+
+# Input is `ld --print-map` format.
+#
# Output is a series of lines in the format "symbol location size
# source". Whitespace may seem silly.
objdump_globals() {
@@ -30,7 +45,9 @@ lint_globals() {
cd "$rel_base"
total=0
while read -r symbol addr size source; do
- : "$addr"
+ if (( addr == 0 )); then
+ continue
+ fi
case "$source" in
/*)
# libg.a(whatever.o) -> libg.a
@@ -38,26 +55,31 @@ lint_globals() {
# resolve `..` components
source="$(realpath --canonicalize-missing --no-symlinks -- "$source")"
;;
- CMakeFiles/*.dir/*.obj)
+ CMakeFiles/*.dir/*.@(obj|o))
# CMakeFiles/sbc_harnes_objs.dir/...
source="${source#CMakeFiles/*.dir/}"
- source="${source%.obj}"
+ source="${source%.@(obj|o)}"
source="${source//__/..}"
source="$(realpath --canonicalize-missing --no-symlinks --relative-to="$topdir" -- "$source")"
;;
esac
- printf '%s %s 0x%04x\n' "$source" "$symbol" "$size"
+ printf "%s %s 0x%04x (%'d)\n" "$source" "$symbol" "$size" "$size"
total=$((total + size))
done
- printf '~ Total 0x%04x\n' "$total"
+ printf "~ Total 0x%04x (%'d)\n" "$total" "$total"
} |
LC_COLLATE=C sort
} | column -t
}
main() {
- echo 'Global variables:'
- lint_globals 'build/rp2040-Release/cmd/sbc_harness/sbc_harness.elf.map' | sed 's/^/ /'
+ local elf
+ for elf in "$@"; do
+ {
+ echo 'Global variables:'
+ lint_globals "${elf}.map" | sed 's/^/ /'
+ } > "${elf%.elf}.lint.globals"
+ done
}
main "$@"
diff --git a/libhw/rp2040_include/libhw/rp2040_hwspi.h b/libhw/rp2040_include/libhw/rp2040_hwspi.h
index b1abe0c..53a7b03 100644
--- a/libhw/rp2040_include/libhw/rp2040_hwspi.h
+++ b/libhw/rp2040_include/libhw/rp2040_hwspi.h
@@ -20,8 +20,9 @@ enum rp2040_hwspi_instance {
struct rp2040_hwspi {
BEGIN_PRIVATE(LIBHW_RP2040_HWSPI_H)
- void /*spi_inst_t*/ *inst;
- uint pin_cs;
+ LM_IF(IS_IMPLEMENTATION_FOR(LIBHW_RP2040_HWSPI_H))(spi_inst_t)(void) *inst;
+
+ uint pin_cs;
END_PRIVATE(LIBHW_RP2040_HWSPI_H)
};
LO_IMPLEMENTATION_H(spi, struct rp2040_hwspi, rp2040_hwspi)
diff --git a/libmisc/include/libmisc/macro.h b/libmisc/include/libmisc/macro.h
index fe61410..b3e235c 100644
--- a/libmisc/include/libmisc/macro.h
+++ b/libmisc/include/libmisc/macro.h
@@ -17,9 +17,11 @@
/* numeric */
#define LM_ARRAY_LEN(ary) (sizeof(ary)/sizeof((ary)[0]))
-#define LM_CEILDIV(n, d) ( ((n)+(d)-1) / (d) )
-#define LM_ROUND_UP(n, d) ( LM_CEILDIV(n, d) * (d) ) /** Return `n` rounded up to the nearest multiple of `d` */
-#define LM_NEXT_POWER_OF_2(x) ( (x) ? 1ULL<<((sizeof(unsigned long long)*8)-__builtin_clzll(x)) : 1)
+#define LM_CEILDIV(n, d) ( ((n)+(d)-1) / (d) ) /** Return ceil(n/d) */
+#define LM_ROUND_UP(n, d) ( LM_CEILDIV(n, d) * (d) ) /** Return `n` rounded up to the nearest multiple of `d` */
+#define LM_ROUND_DOWN(n, d) ( ((n)/(d)) * (d) ) /** Return `n` rounded down to the nearest multiple of `d` */
+#define LM_NEXT_POWER_OF_2(x) ( (x) ? 1ULL<<((sizeof(unsigned long long)*8)-__builtin_clzll(x)) : 1) /** Return the lowest power of 2 that is > x */
+#define LM_FLOORLOG2(x) ((sizeof(unsigned long long)*8)-__builtin_clzll(x)-1) /** Return floor(log_2(x) */
/* strings */
diff --git a/libmisc/include/libmisc/private.h b/libmisc/include/libmisc/private.h
index 1db7915..c5382a7 100644
--- a/libmisc/include/libmisc/private.h
+++ b/libmisc/include/libmisc/private.h
@@ -1,6 +1,6 @@
/* libmisc/private.h - Utilities to hide struct fields
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@@ -10,7 +10,8 @@
#include <libmisc/macro.h>
#define YES LM_SENTINEL()
-#define BEGIN_PRIVATE(name) LM_IF(LM_IS_SENTINEL(IMPLEMENTATION_FOR_##name))()(struct {)
-#define END_PRIVATE(name) LM_IF(LM_IS_SENTINEL(IMPLEMENTATION_FOR_##name))()(} LM_CAT2_(_HIDDEN_, __COUNTER__);)
+#define IS_IMPLEMENTATION_FOR(name) LM_IS_SENTINEL(IMPLEMENTATION_FOR_##name)
+#define BEGIN_PRIVATE(name) LM_IF(IS_IMPLEMENTATION_FOR(name))()(struct {)
+#define END_PRIVATE(name) LM_IF(IS_IMPLEMENTATION_FOR(name))()(} LM_CAT2_(_HIDDEN_, __COUNTER__);)
#endif /* _LIBMISC_PRIVATE_H_ */
diff --git a/libmisc/tests/test_macro.c b/libmisc/tests/test_macro.c
index 7cbf9d3..69655d1 100644
--- a/libmisc/tests/test_macro.c
+++ b/libmisc/tests/test_macro.c
@@ -1,6 +1,6 @@
/* libmisc/tests/test_macro.c - Tests for <libmisc/macro.h>
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@@ -9,6 +9,7 @@
#include "test.h"
int main() {
+ printf("== LM_NEXT_POWER_OF_2 =====================================\n");
/* valid down to 0. */
test_assert(LM_NEXT_POWER_OF_2(0) == 1);
test_assert(LM_NEXT_POWER_OF_2(1) == 2);
@@ -28,5 +29,27 @@ int main() {
/* Valid up to 0x8000000000000000-1 = (1<<63)-1 */
test_assert(LM_NEXT_POWER_OF_2(0x8000000000000000) == 0); /* :( */
+ printf("== LM_FLOORLOG2 ===========================================\n");
+ /* valid down to 1. */
+ test_assert(LM_FLOORLOG2(1) == 0);
+ test_assert(LM_FLOORLOG2(2) == 1);
+ test_assert(LM_FLOORLOG2(3) == 1);
+ test_assert(LM_FLOORLOG2(4) == 2);
+ test_assert(LM_FLOORLOG2(5) == 2);
+ test_assert(LM_FLOORLOG2(6) == 2);
+ test_assert(LM_FLOORLOG2(7) == 2);
+ test_assert(LM_FLOORLOG2(8) == 3);
+ /* ... */
+ test_assert(LM_FLOORLOG2(16) == 4);
+ /* ... */
+ test_assert(LM_FLOORLOG2(0x80000000) == 31);
+ /* ... */
+ test_assert(LM_FLOORLOG2(0xFFFFFFFF) == 31);
+ test_assert(LM_FLOORLOG2(0x100000000) == 32);
+ /* ... */
+ test_assert(LM_FLOORLOG2(0x8000000000000000) == 63);
+ /* ... */
+ test_assert(LM_FLOORLOG2(0xFFFFFFFFFFFFFFFF) == 63);
+
return 0;
}