Implement allocator tracing and optimize internal RAM usage
This commit is contained in:
parent
c7e0ec45ca
commit
d555c908a2
128
firmware/Cargo.lock
generated
128
firmware/Cargo.lock
generated
|
|
@ -26,17 +26,17 @@ dependencies = [
|
||||||
"embedded-storage-async",
|
"embedded-storage-async",
|
||||||
"embuild",
|
"embuild",
|
||||||
"enumset",
|
"enumset",
|
||||||
"esp-alloc",
|
"esp-alloc 0.9.0 (git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1)",
|
||||||
"esp-backtrace",
|
"esp-backtrace",
|
||||||
"esp-bootloader-esp-idf",
|
"esp-bootloader-esp-idf",
|
||||||
"esp-hal",
|
"esp-hal",
|
||||||
"esp-hal-bounce-buffers",
|
"esp-hal-bounce-buffers",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-println",
|
"esp-println",
|
||||||
"esp-radio",
|
"esp-radio",
|
||||||
"esp-rtos",
|
"esp-rtos",
|
||||||
"esp-storage",
|
"esp-storage",
|
||||||
"esp-sync",
|
"esp-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gix",
|
"gix",
|
||||||
"hex",
|
"hex",
|
||||||
"hmac",
|
"hmac",
|
||||||
|
|
@ -2044,8 +2044,23 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"document-features",
|
"document-features",
|
||||||
"enumset",
|
"enumset",
|
||||||
"esp-config",
|
"esp-config 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-sync",
|
"esp-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"linked_list_allocator",
|
||||||
|
"rlsf",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "esp-alloc"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1#ee6e26f2fefa4da2168c95839bf618e1ecc22cc1"
|
||||||
|
dependencies = [
|
||||||
|
"allocator-api2 0.3.1",
|
||||||
|
"cfg-if",
|
||||||
|
"document-features",
|
||||||
|
"enumset",
|
||||||
|
"esp-config 0.6.1 (git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1)",
|
||||||
|
"esp-sync 0.1.1 (git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1)",
|
||||||
"linked_list_allocator",
|
"linked_list_allocator",
|
||||||
"rlsf",
|
"rlsf",
|
||||||
]
|
]
|
||||||
|
|
@ -2058,13 +2073,13 @@ checksum = "3318413fb566c7227387f67736cf70cd74d80a11f2bb31c7b95a9eb48d079669"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"document-features",
|
"document-features",
|
||||||
"esp-config",
|
"esp-config 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-println",
|
"esp-println",
|
||||||
"heapless 0.9.2",
|
"heapless 0.9.2",
|
||||||
"riscv",
|
"riscv",
|
||||||
"semihosting",
|
"semihosting",
|
||||||
"xtensa-lx",
|
"xtensa-lx 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2076,9 +2091,9 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"document-features",
|
"document-features",
|
||||||
"embedded-storage",
|
"embedded-storage",
|
||||||
"esp-config",
|
"esp-config 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-hal-procmacros",
|
"esp-hal-procmacros",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-rom-sys",
|
"esp-rom-sys",
|
||||||
"jiff",
|
"jiff",
|
||||||
"log",
|
"log",
|
||||||
|
|
@ -2092,7 +2107,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "102871054f8dd98202177b9890cb4b71d0c6fe1f1413b7a379a8e0841fc2473c"
|
checksum = "102871054f8dd98202177b9890cb4b71d0c6fe1f1413b7a379a8e0841fc2473c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"document-features",
|
"document-features",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde",
|
||||||
|
"serde_yaml",
|
||||||
|
"somni-expr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "esp-config"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1#ee6e26f2fefa4da2168c95839bf618e1ecc22cc1"
|
||||||
|
dependencies = [
|
||||||
|
"document-features",
|
||||||
|
"esp-metadata-generated 0.3.0 (git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1)",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"somni-expr",
|
"somni-expr",
|
||||||
|
|
@ -2125,12 +2152,12 @@ dependencies = [
|
||||||
"embedded-io-async 0.6.1",
|
"embedded-io-async 0.6.1",
|
||||||
"embedded-io-async 0.7.0",
|
"embedded-io-async 0.7.0",
|
||||||
"enumset",
|
"enumset",
|
||||||
"esp-config",
|
"esp-config 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-hal-procmacros",
|
"esp-hal-procmacros",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-riscv-rt",
|
"esp-riscv-rt",
|
||||||
"esp-rom-sys",
|
"esp-rom-sys",
|
||||||
"esp-sync",
|
"esp-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-synopsys-usb-otg",
|
"esp-synopsys-usb-otg",
|
||||||
"esp32",
|
"esp32",
|
||||||
"esp32c2",
|
"esp32c2",
|
||||||
|
|
@ -2150,7 +2177,7 @@ dependencies = [
|
||||||
"riscv",
|
"riscv",
|
||||||
"strum",
|
"strum",
|
||||||
"ufmt-write",
|
"ufmt-write",
|
||||||
"xtensa-lx",
|
"xtensa-lx 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"xtensa-lx-rt",
|
"xtensa-lx-rt",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2185,6 +2212,11 @@ version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a93e39c8ad8d390d248dc7b9f4b59a873f313bf535218b8e2351356972399e3"
|
checksum = "9a93e39c8ad8d390d248dc7b9f4b59a873f313bf535218b8e2351356972399e3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "esp-metadata-generated"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1#ee6e26f2fefa4da2168c95839bf618e1ecc22cc1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "esp-phy"
|
name = "esp-phy"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
|
@ -2193,10 +2225,10 @@ checksum = "6b1facf348e1e251517278fc0f5dc134e95e518251f5796cfbb532ca226a29bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"document-features",
|
"document-features",
|
||||||
"esp-config",
|
"esp-config 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-hal",
|
"esp-hal",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-sync",
|
"esp-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-wifi-sys",
|
"esp-wifi-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2207,8 +2239,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a30e6c9fbcc01c348d46706fef8131c7775ab84c254a3cd65d0cd3f6414d592"
|
checksum = "5a30e6c9fbcc01c348d46706fef8131c7775ab84c254a3cd65d0cd3f6414d592"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"document-features",
|
"document-features",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-sync",
|
"esp-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log",
|
"log",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
]
|
]
|
||||||
|
|
@ -2227,14 +2259,14 @@ dependencies = [
|
||||||
"embedded-io 0.7.1",
|
"embedded-io 0.7.1",
|
||||||
"embedded-io-async 0.6.1",
|
"embedded-io-async 0.6.1",
|
||||||
"embedded-io-async 0.7.0",
|
"embedded-io-async 0.7.0",
|
||||||
"esp-alloc",
|
"esp-alloc 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-config",
|
"esp-config 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-hal",
|
"esp-hal",
|
||||||
"esp-hal-procmacros",
|
"esp-hal-procmacros",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-phy",
|
"esp-phy",
|
||||||
"esp-radio-rtos-driver",
|
"esp-radio-rtos-driver",
|
||||||
"esp-sync",
|
"esp-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-wifi-sys",
|
"esp-wifi-sys",
|
||||||
"heapless 0.9.2",
|
"heapless 0.9.2",
|
||||||
"instability",
|
"instability",
|
||||||
|
|
@ -2270,7 +2302,7 @@ checksum = "cd66cccc6dd2d13e9f33668a57717ab14a6d217180ec112e6be533de93e7ecbf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"document-features",
|
"document-features",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2286,12 +2318,12 @@ dependencies = [
|
||||||
"embassy-sync 0.7.2",
|
"embassy-sync 0.7.2",
|
||||||
"embassy-time-driver",
|
"embassy-time-driver",
|
||||||
"embassy-time-queue-utils",
|
"embassy-time-queue-utils",
|
||||||
"esp-config",
|
"esp-config 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-hal",
|
"esp-hal",
|
||||||
"esp-hal-procmacros",
|
"esp-hal-procmacros",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-radio-rtos-driver",
|
"esp-radio-rtos-driver",
|
||||||
"esp-sync",
|
"esp-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2305,9 +2337,9 @@ dependencies = [
|
||||||
"embedded-storage",
|
"embedded-storage",
|
||||||
"esp-hal",
|
"esp-hal",
|
||||||
"esp-hal-procmacros",
|
"esp-hal-procmacros",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"esp-rom-sys",
|
"esp-rom-sys",
|
||||||
"esp-sync",
|
"esp-sync 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2320,10 +2352,24 @@ dependencies = [
|
||||||
"document-features",
|
"document-features",
|
||||||
"embassy-sync 0.6.2",
|
"embassy-sync 0.6.2",
|
||||||
"embassy-sync 0.7.2",
|
"embassy-sync 0.7.2",
|
||||||
"esp-metadata-generated",
|
"esp-metadata-generated 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log",
|
"log",
|
||||||
"riscv",
|
"riscv",
|
||||||
"xtensa-lx",
|
"xtensa-lx 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "esp-sync"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1#ee6e26f2fefa4da2168c95839bf618e1ecc22cc1"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"document-features",
|
||||||
|
"embassy-sync 0.6.2",
|
||||||
|
"embassy-sync 0.7.2",
|
||||||
|
"esp-metadata-generated 0.3.0 (git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1)",
|
||||||
|
"riscv",
|
||||||
|
"xtensa-lx 0.13.0 (git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -8516,6 +8562,14 @@ dependencies = [
|
||||||
"critical-section",
|
"critical-section",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xtensa-lx"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "git+https://github.com/esp-rs/esp-hal?rev=ee6e26f2fefa4da2168c95839bf618e1ecc22cc1#ee6e26f2fefa4da2168c95839bf618e1ecc22cc1"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xtensa-lx-rt"
|
name = "xtensa-lx-rt"
|
||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
|
|
@ -8523,7 +8577,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8709f037fb123fe7ff146d2bce86f9dc0dfc53045c016bfd9d703317b6502845"
|
checksum = "8709f037fb123fe7ff146d2bce86f9dc0dfc53045c016bfd9d703317b6502845"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"document-features",
|
"document-features",
|
||||||
"xtensa-lx",
|
"xtensa-lx 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"xtensa-lx-rt-proc-macros",
|
"xtensa-lx-rt-proc-macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -8848,3 +8902,11 @@ dependencies = [
|
||||||
"syn 2.0.114",
|
"syn 2.0.114",
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[patch.unused]]
|
||||||
|
name = "i-slint-core"
|
||||||
|
version = "1.14.1"
|
||||||
|
|
||||||
|
[[patch.unused]]
|
||||||
|
name = "slint"
|
||||||
|
version = "1.14.1"
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ rustflags = [
|
||||||
|
|
||||||
# Required to obtain backtraces on riscv (e.g. when using the "esp-backtrace" crate.)
|
# Required to obtain backtraces on riscv (e.g. when using the "esp-backtrace" crate.)
|
||||||
# "-C", "force-frame-pointers",
|
# "-C", "force-frame-pointers",
|
||||||
|
|
||||||
|
# Output linker map
|
||||||
|
# "-C", "link-arg=-Wl,-Map=target/linker.map"
|
||||||
]
|
]
|
||||||
|
|
||||||
[env] # These must be kept in sync with /.zed/settings.json
|
[env] # These must be kept in sync with /.zed/settings.json
|
||||||
|
|
@ -40,11 +43,11 @@ ACID_COMPOSE_LOCALE = "cs_CZ.UTF-8"
|
||||||
build-std = ["alloc", "core"]
|
build-std = ["alloc", "core"]
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
# esp-backtrace = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
esp-backtrace = { git = "https://github.com/Limeth/esp-hal.git", rev = "114977583886be4ed866ad7b7c6f16865148e899" }
|
||||||
|
esp-println = { git = "https://github.com/Limeth/esp-hal.git", rev = "114977583886be4ed866ad7b7c6f16865148e899" }
|
||||||
# esp-hal = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
# esp-hal = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
||||||
# esp-storage = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
# esp-storage = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
||||||
# esp-alloc = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
# esp-alloc = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
||||||
# esp-println = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
|
||||||
# esp-radio = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
# esp-radio = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
||||||
# esp-rtos = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
# esp-rtos = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
||||||
# esp-bootloader-esp-idf = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
# esp-bootloader-esp-idf = { git = "https://github.com/Limeth/esp-hal.git", rev = "95d8c8b046e945e41294d5577528d0a1c4b03247" }
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ description = "Firmware for the ACID keyboard"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["usb-log", "limit-fps"]
|
default = ["usb-log", "limit-fps", "no-alloc-tracing"]
|
||||||
# Make RMK not to use USB
|
# Make RMK not to use USB
|
||||||
no-usb = ["rmk/_no_usb"]
|
no-usb = ["rmk/_no_usb"]
|
||||||
# Let RMK use BLE
|
# Let RMK use BLE
|
||||||
|
|
@ -32,6 +32,8 @@ probe = ["limit-fps", "rtt-log", "no-usb", "ble"]
|
||||||
format-db = []
|
format-db = []
|
||||||
# Avoid entering the critical section for the whole duration of printing a message to console.
|
# Avoid entering the critical section for the whole duration of printing a message to console.
|
||||||
racy-logging = []
|
racy-logging = []
|
||||||
|
# Global allocator tracing proxy
|
||||||
|
no-alloc-tracing = ["esp-alloc/global-allocator"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rmk = { version = "0.8.2", git = "https://github.com/Limeth/rmk", rev = "1661c55f5c21e7d80ea3f93255df483302c74b84", default-features = false, features = [
|
rmk = { version = "0.8.2", git = "https://github.com/Limeth/rmk", rev = "1661c55f5c21e7d80ea3f93255df483302c74b84", default-features = false, features = [
|
||||||
|
|
@ -51,7 +53,7 @@ esp-backtrace = { version = "0.18", default-features = false, features = [
|
||||||
] }
|
] }
|
||||||
esp-hal = { version = "1.0", features = ["esp32s3", "unstable", "psram", "log-04"] }
|
esp-hal = { version = "1.0", features = ["esp32s3", "unstable", "psram", "log-04"] }
|
||||||
esp-storage = { version = "0.8", features = ["esp32s3"] }
|
esp-storage = { version = "0.8", features = ["esp32s3"] }
|
||||||
esp-alloc = { version = "0.9", features = ["nightly"] }
|
esp-alloc = { version = "0.9", git = "https://github.com/esp-rs/esp-hal", rev = "ee6e26f2fefa4da2168c95839bf618e1ecc22cc1", default-features = false, features = ["esp32s3", "nightly", "compat"] }
|
||||||
esp-println = { version = "0.16", features = ["esp32s3", "log-04"] }
|
esp-println = { version = "0.16", features = ["esp32s3", "log-04"] }
|
||||||
esp-radio = { version = "0.17", features = ["esp32s3", "unstable", "ble"], optional = true }
|
esp-radio = { version = "0.17", features = ["esp32s3", "unstable", "ble"], optional = true }
|
||||||
esp-rtos = { version = "0.2", features = ["esp32s3", "esp-radio", "embassy"] }
|
esp-rtos = { version = "0.2", features = ["esp32s3", "esp-radio", "embassy"] }
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use esp_hal::rng::Trng;
|
||||||
use esp_storage::FlashStorage;
|
use esp_storage::FlashStorage;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
|
|
||||||
use crate::ram::PSRAM_ALLOCATOR;
|
use crate::ram::{PSRAM_ALLOCATOR, PsramAllocator};
|
||||||
|
|
||||||
pub type PartitionAcid =
|
pub type PartitionAcid =
|
||||||
Partition<'static, CriticalSectionRawMutex, BlockingAsync<FlashStorage<'static>>>;
|
Partition<'static, CriticalSectionRawMutex, BlockingAsync<FlashStorage<'static>>>;
|
||||||
|
|
@ -27,7 +27,7 @@ struct AlignedBuf<const N: usize>(pub [u8; N]);
|
||||||
|
|
||||||
pub struct EkvFlash<T> {
|
pub struct EkvFlash<T> {
|
||||||
flash: T,
|
flash: T,
|
||||||
buffer: Box<AlignedBuf<{ ekv::config::PAGE_SIZE }>, &'static esp_alloc::EspHeap>,
|
buffer: Box<AlignedBuf<{ ekv::config::PAGE_SIZE }>, PsramAllocator>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EkvFlash<T> {
|
impl<T> EkvFlash<T> {
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,8 @@ pub unsafe extern "C" fn __xkbc_atoi(s: *const c_char) -> c_int {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: What is this even for?
|
// A pointer to an array of character attributes.
|
||||||
|
// This is used by `isdigit()`, `isalpha()`, `isspace()`, etc.
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub static __spre__ctype_: [c_char; 0] = [];
|
pub static __spre__ctype_: [c_char; 0] = [];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use log::info;
|
||||||
use rmk::storage::async_flash_wrapper;
|
use rmk::storage::async_flash_wrapper;
|
||||||
use static_cell::StaticCell;
|
use static_cell::StaticCell;
|
||||||
|
|
||||||
use crate::PSRAM_ALLOCATOR;
|
use crate::{PSRAM_ALLOCATOR, ram::PsramAllocator};
|
||||||
|
|
||||||
pub type Partition = embassy_embedded_hal::flash::partition::Partition<
|
pub type Partition = embassy_embedded_hal::flash::partition::Partition<
|
||||||
'static,
|
'static,
|
||||||
|
|
@ -25,8 +25,7 @@ pub struct Partitions {
|
||||||
|
|
||||||
/// Initialize the flash
|
/// Initialize the flash
|
||||||
pub fn initialize(flash_peripheral: esp_hal::peripherals::FLASH<'static>) -> Partitions {
|
pub fn initialize(flash_peripheral: esp_hal::peripherals::FLASH<'static>) -> Partitions {
|
||||||
static PARTITION_TABLE_BUFFER: StaticCell<Vec<u8, &'static esp_alloc::EspHeap>> =
|
static PARTITION_TABLE_BUFFER: StaticCell<Vec<u8, PsramAllocator>> = StaticCell::new();
|
||||||
StaticCell::new();
|
|
||||||
let partition_table_buffer = PARTITION_TABLE_BUFFER.init_with(|| {
|
let partition_table_buffer = PARTITION_TABLE_BUFFER.init_with(|| {
|
||||||
let mut buffer = Vec::<u8, _>::new_in(&PSRAM_ALLOCATOR);
|
let mut buffer = Vec::<u8, _>::new_in(&PSRAM_ALLOCATOR);
|
||||||
buffer.resize(
|
buffer.resize(
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(allocator_api)]
|
#![feature(allocator_api)]
|
||||||
|
#![feature(btreemap_alloc)]
|
||||||
#![feature(macro_metavar_expr)]
|
#![feature(macro_metavar_expr)]
|
||||||
#![feature(c_variadic)]
|
#![feature(c_variadic)]
|
||||||
#![feature(c_size_t)]
|
#![feature(c_size_t)]
|
||||||
|
|
@ -391,7 +392,7 @@ async fn main_task(peripherals: MainPeripherals) {
|
||||||
|
|
||||||
// TODO: Probably want to select! instead and re-try.
|
// TODO: Probably want to select! instead and re-try.
|
||||||
join_all![
|
join_all![
|
||||||
run_alloc_stats_reporter(),
|
ram::run_alloc_stats_reporter(),
|
||||||
initialize_and_run_rmk_devices(peripherals.matrix),
|
initialize_and_run_rmk_devices(peripherals.matrix),
|
||||||
keyboard.run(), // Keyboard is special
|
keyboard.run(), // Keyboard is special
|
||||||
run_rmk(
|
run_rmk(
|
||||||
|
|
@ -418,34 +419,6 @@ async fn main_task(peripherals: MainPeripherals) {
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_alloc_stats_reporter() {
|
|
||||||
let mut psram_used_prev = 0;
|
|
||||||
let mut heap_used_prev = 0;
|
|
||||||
loop {
|
|
||||||
let psram_stats = PSRAM_ALLOCATOR.stats();
|
|
||||||
let heap_stats = esp_alloc::HEAP.stats();
|
|
||||||
if psram_stats.current_usage != psram_used_prev {
|
|
||||||
let difference = psram_stats.current_usage as isize - psram_used_prev as isize;
|
|
||||||
psram_used_prev = psram_stats.current_usage;
|
|
||||||
warn!(
|
|
||||||
"PSRAM usage changed: {}{}\n{psram_stats}",
|
|
||||||
if difference < 0 { '-' } else { '+' },
|
|
||||||
difference.abs()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if heap_stats.current_usage != heap_used_prev {
|
|
||||||
let difference = heap_stats.current_usage as isize - heap_used_prev as isize;
|
|
||||||
heap_used_prev = heap_stats.current_usage;
|
|
||||||
warn!(
|
|
||||||
"HEAP usage changed: {}{}\n{heap_stats}",
|
|
||||||
if difference < 0 { '-' } else { '+' },
|
|
||||||
difference.abs()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Timer::after_secs(1).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn initialize_and_run_rmk_devices(matrix_peripherals: MatrixPeripherals) {
|
async fn initialize_and_run_rmk_devices(matrix_peripherals: MatrixPeripherals) {
|
||||||
// Initialize the matrix and keyboard
|
// Initialize the matrix and keyboard
|
||||||
const I2C_ADDR_MATRIX_LEFT: I2cAddress = I2cAddress::SevenBit(0b0100000);
|
const I2C_ADDR_MATRIX_LEFT: I2cAddress = I2cAddress::SevenBit(0b0100000);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use alloc::vec::Vec;
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::channel::Channel;
|
use embassy_sync::channel::Channel;
|
||||||
use embassy_time::Instant;
|
use embassy_time::Instant;
|
||||||
use esp_alloc::{EspHeap, MemoryCapability};
|
use esp_alloc::MemoryCapability;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rmk::descriptor::KeyboardReport;
|
use rmk::descriptor::KeyboardReport;
|
||||||
use rmk::hid::Report;
|
use rmk::hid::Report;
|
||||||
|
|
@ -19,6 +19,7 @@ use rmk::{heapless, join_all};
|
||||||
use slint::platform::Key;
|
use slint::platform::Key;
|
||||||
use xkbcommon::xkb::{self, FeedResult, KeyDirection, Keysym, ModMask, Status};
|
use xkbcommon::xkb::{self, FeedResult, KeyDirection, Keysym, ModMask, Status};
|
||||||
|
|
||||||
|
use crate::ram::PsramAllocator;
|
||||||
use crate::util::{DurationExt, get_file_name};
|
use crate::util::{DurationExt, get_file_name};
|
||||||
use crate::{KEYBOARD_REPORT_PROXY, PSRAM_ALLOCATOR};
|
use crate::{KEYBOARD_REPORT_PROXY, PSRAM_ALLOCATOR};
|
||||||
|
|
||||||
|
|
@ -401,8 +402,8 @@ struct KeysymEntry {
|
||||||
mask: xkb::ModMask,
|
mask: xkb::ModMask,
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeysymEntries = Vec<KeysymEntry, &'static EspHeap>;
|
type KeysymEntries = Vec<KeysymEntry, PsramAllocator>;
|
||||||
type KeysymMap = BTreeMap<Keysym, KeysymEntries, &'static EspHeap>;
|
type KeysymMap = BTreeMap<Keysym, KeysymEntries, PsramAllocator>;
|
||||||
|
|
||||||
/// Based on https://github.com/xkbcommon/libxkbcommon/blob/6c67e3d41d3215ab1edd4406de215c7bf1f20c74/tools/how-to-type.c#L434
|
/// Based on https://github.com/xkbcommon/libxkbcommon/blob/6c67e3d41d3215ab1edd4406de215c7bf1f20c74/tools/how-to-type.c#L434
|
||||||
fn lookup_keysym_entries(
|
fn lookup_keysym_entries(
|
||||||
|
|
@ -427,7 +428,7 @@ pub fn string_to_hid_keycodes(
|
||||||
keymap: &xkb::Keymap,
|
keymap: &xkb::Keymap,
|
||||||
_compose_table: &xkb::compose::Table,
|
_compose_table: &xkb::compose::Table,
|
||||||
string: &str,
|
string: &str,
|
||||||
) -> Result<Vec<HidKeycodeWithMods, &'static EspHeap>, char> {
|
) -> Result<Vec<HidKeycodeWithMods, PsramAllocator>, char> {
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
struct KeycodeChoice {
|
struct KeycodeChoice {
|
||||||
mod_mask: ModMask,
|
mod_mask: ModMask,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
|
use embassy_time::Timer;
|
||||||
use esp_alloc::{HeapRegion, MemoryCapability};
|
use esp_alloc::{HeapRegion, MemoryCapability};
|
||||||
use esp_hal::ram;
|
use esp_hal::ram;
|
||||||
use log::info;
|
use log::{info, warn};
|
||||||
|
|
||||||
// Memory allocation regions.
|
// Memory allocation regions.
|
||||||
// These can be debugged using `xtensa-esp32s3-elf-size -A <path-to-binary>`.
|
// These can be debugged using `xtensa-esp32s3-elf-size -A <path-to-binary>`.
|
||||||
// A panic such as `memory allocation of 3740121773 bytes failed` is caused by a heap overflow. The size is `DEEDBAAD` in hex.
|
// A panic such as `memory allocation of 3740121773 bytes failed` is caused by a heap overflow. The size is `DEEDBAAD` in hex.
|
||||||
|
//
|
||||||
|
// RAM usage of static variables can be diagnosed with:
|
||||||
|
// ```sh
|
||||||
|
// xtensa-esp32s3-elf-nm.exe -S --size-sort -t d ../target/xtensa-esp32s3-none-elf/release/acid-firmware | grep -iE ' [dbv] ' | tail -n 10 | tac
|
||||||
|
// ```
|
||||||
|
|
||||||
/// Total heap size
|
/// Total heap size
|
||||||
pub const HEAP_SIZE: usize = 112 * 1024;
|
pub const HEAP_SIZE: usize = 112 * 1024;
|
||||||
|
|
@ -12,6 +18,7 @@ pub const HEAP_SIZE: usize = 112 * 1024;
|
||||||
pub const STACK_SIZE_CORE_APP: usize = 80 * 1024;
|
pub const STACK_SIZE_CORE_APP: usize = 80 * 1024;
|
||||||
|
|
||||||
pub static PSRAM_ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
|
pub static PSRAM_ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
|
||||||
|
pub type PsramAllocator = &'static esp_alloc::EspHeap;
|
||||||
|
|
||||||
pub fn initialize(psram_peripheral: esp_hal::peripherals::PSRAM) {
|
pub fn initialize(psram_peripheral: esp_hal::peripherals::PSRAM) {
|
||||||
// Use the internal DRAM as the heap.
|
// Use the internal DRAM as the heap.
|
||||||
|
|
@ -23,6 +30,10 @@ pub fn initialize(psram_peripheral: esp_hal::peripherals::PSRAM) {
|
||||||
|
|
||||||
esp_alloc::heap_allocator!(#[ram(reclaimed)] size: HEAP_SIZE_RECLAIMED);
|
esp_alloc::heap_allocator!(#[ram(reclaimed)] size: HEAP_SIZE_RECLAIMED);
|
||||||
esp_alloc::heap_allocator!(size: HEAP_SIZE - HEAP_SIZE_RECLAIMED);
|
esp_alloc::heap_allocator!(size: HEAP_SIZE - HEAP_SIZE_RECLAIMED);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no-alloc-tracing"))]
|
||||||
|
alloc_tracing::install_iram_allocator_proxy();
|
||||||
|
|
||||||
info!("IRAM heap initialized!\n{}", esp_alloc::HEAP.stats());
|
info!("IRAM heap initialized!\n{}", esp_alloc::HEAP.stats());
|
||||||
|
|
||||||
// Initialize the PSRAM allocator.
|
// Initialize the PSRAM allocator.
|
||||||
|
|
@ -42,3 +53,318 @@ pub fn initialize(psram_peripheral: esp_hal::peripherals::PSRAM) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn run_alloc_stats_reporter() {
|
||||||
|
let mut psram_used_prev = 0;
|
||||||
|
let mut heap_used_prev = 0;
|
||||||
|
loop {
|
||||||
|
let psram_stats = PSRAM_ALLOCATOR.stats();
|
||||||
|
let heap_stats = esp_alloc::HEAP.stats();
|
||||||
|
if psram_stats.current_usage != psram_used_prev {
|
||||||
|
let difference = psram_stats.current_usage as isize - psram_used_prev as isize;
|
||||||
|
psram_used_prev = psram_stats.current_usage;
|
||||||
|
warn!(
|
||||||
|
"PSRAM heap usage changed: {}{}\n{psram_stats}",
|
||||||
|
if difference < 0 { '-' } else { '+' },
|
||||||
|
difference.abs()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if heap_stats.current_usage != heap_used_prev {
|
||||||
|
let difference = heap_stats.current_usage as isize - heap_used_prev as isize;
|
||||||
|
heap_used_prev = heap_stats.current_usage;
|
||||||
|
warn!(
|
||||||
|
"IRAM heap usage changed: {}{}\n{heap_stats}",
|
||||||
|
if difference < 0 { '-' } else { '+' },
|
||||||
|
difference.abs()
|
||||||
|
);
|
||||||
|
#[cfg(not(feature = "no-alloc-tracing"))]
|
||||||
|
alloc_tracing::report_stats();
|
||||||
|
}
|
||||||
|
Timer::after_secs(1).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no-alloc-tracing"))]
|
||||||
|
mod alloc_tracing {
|
||||||
|
use core::{
|
||||||
|
alloc::GlobalAlloc,
|
||||||
|
cell::RefCell,
|
||||||
|
cmp::{Ordering, Reverse},
|
||||||
|
fmt::Display,
|
||||||
|
};
|
||||||
|
|
||||||
|
use alloc::collections::btree_map::BTreeMap;
|
||||||
|
use embassy_sync::blocking_mutex::{Mutex, raw::CriticalSectionRawMutex};
|
||||||
|
use esp_alloc::EspHeap;
|
||||||
|
use esp_backtrace::Backtrace;
|
||||||
|
use esp_sync::NonReentrantMutex;
|
||||||
|
use log::warn;
|
||||||
|
use tinyvec::ArrayVec;
|
||||||
|
|
||||||
|
use crate::ram::{PSRAM_ALLOCATOR, PsramAllocator};
|
||||||
|
|
||||||
|
#[derive(Default, Clone, PartialEq, Eq, Debug)]
|
||||||
|
struct Stats {
|
||||||
|
/// The total number of allocations.
|
||||||
|
allocations: usize,
|
||||||
|
/// The number of bytes allocated in total.
|
||||||
|
allocated_total: usize,
|
||||||
|
/// The number of bytes allocated minus the number of bytes deallocated.
|
||||||
|
allocated_current: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stats {
|
||||||
|
fn update(&mut self, allocations_delta: isize, bytes_delta: isize, bytes_new: usize) {
|
||||||
|
self.allocations = (self.allocations as isize + allocations_delta) as usize;
|
||||||
|
self.allocated_total += bytes_new;
|
||||||
|
self.allocated_current = (self.allocated_current as isize + bytes_delta) as usize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Stats {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for Stats {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
self.allocated_current
|
||||||
|
.cmp(&other.allocated_current)
|
||||||
|
.then_with(|| self.allocated_total.cmp(&other.allocated_total).reverse())
|
||||||
|
.then_with(|| self.allocations.cmp(&other.allocations).reverse())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct BacktraceWrapper(Backtrace);
|
||||||
|
|
||||||
|
impl Display for BacktraceWrapper {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
let mut it = self.0.frames().iter();
|
||||||
|
if let Some(frame) = it.next() {
|
||||||
|
write!(f, "0x{:08x}", frame.program_counter())?;
|
||||||
|
}
|
||||||
|
while let Some(frame) = it.next() {
|
||||||
|
write!(f, " 0x{:08x}", frame.program_counter())?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for BacktraceWrapper {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
if self.0.frames().len() != other.0.frames().len() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (lhs_frame, rhs_frame) in self.0.frames().iter().zip(other.0.frames()) {
|
||||||
|
if lhs_frame.program_counter() != rhs_frame.program_counter() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for BacktraceWrapper {}
|
||||||
|
|
||||||
|
impl PartialOrd for BacktraceWrapper {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for BacktraceWrapper {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
let mut lhs_it = self.0.frames().iter().rev();
|
||||||
|
let mut rhs_it = other.0.frames().iter().rev();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match (lhs_it.next(), rhs_it.next()) {
|
||||||
|
(Some(lhs_frame), Some(rhs_frame)) => {
|
||||||
|
let ordering = lhs_frame
|
||||||
|
.program_counter()
|
||||||
|
.cmp(&rhs_frame.program_counter());
|
||||||
|
|
||||||
|
if ordering != Ordering::Equal {
|
||||||
|
return ordering;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(Some(_), None) => return Ordering::Greater,
|
||||||
|
(None, Some(_)) => return Ordering::Less,
|
||||||
|
(None, None) => return Ordering::Equal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct AllocationTracer {
|
||||||
|
bt_to_stats: BTreeMap<BacktraceWrapper, Stats, PsramAllocator>,
|
||||||
|
ptr_to_bt: BTreeMap<*mut u8, BacktraceWrapper, PsramAllocator>,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for AllocationTracer {}
|
||||||
|
|
||||||
|
impl AllocationTracer {
|
||||||
|
const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
bt_to_stats: BTreeMap::new_in(&PSRAM_ALLOCATOR),
|
||||||
|
ptr_to_bt: BTreeMap::new_in(&PSRAM_ALLOCATOR),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc(&mut self, bt: Backtrace, ptr: *mut u8, bytes: usize) {
|
||||||
|
let bt = BacktraceWrapper(bt.clone());
|
||||||
|
self.ptr_to_bt.insert(ptr, bt.clone());
|
||||||
|
let stats = self
|
||||||
|
.bt_to_stats
|
||||||
|
.entry(bt)
|
||||||
|
.or_insert_with(|| Default::default());
|
||||||
|
stats.update(1, bytes as isize, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn realloc(
|
||||||
|
&mut self,
|
||||||
|
ptr_old: *mut u8,
|
||||||
|
ptr_new: *mut u8,
|
||||||
|
bytes_old: usize,
|
||||||
|
bytes_new: usize,
|
||||||
|
) {
|
||||||
|
let bt = self.ptr_to_bt.remove(&ptr_old).unwrap();
|
||||||
|
self.ptr_to_bt.insert(ptr_new, bt.clone());
|
||||||
|
let stats = self.bt_to_stats.get_mut(&bt).unwrap();
|
||||||
|
stats.update(0, bytes_new as isize - bytes_old as isize, bytes_new);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dealloc(&mut self, ptr: *mut u8, bytes: usize) {
|
||||||
|
let bt = self.ptr_to_bt.remove(&ptr).unwrap();
|
||||||
|
let stats = self.bt_to_stats.get_mut(&bt).unwrap();
|
||||||
|
stats.update(-1, -(bytes as isize), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TracingAllocator<T: GlobalAlloc + 'static> {
|
||||||
|
inner: NonReentrantMutex<Option<&'static T>>,
|
||||||
|
tracer: Mutex<CriticalSectionRawMutex, RefCell<AllocationTracer>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> TracingAllocator<T>
|
||||||
|
where
|
||||||
|
T: GlobalAlloc,
|
||||||
|
{
|
||||||
|
const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: NonReentrantMutex::new(None),
|
||||||
|
tracer: Mutex::new(RefCell::new(AllocationTracer::new())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_inner<R>(&self, callback: impl FnOnce(&T) -> R) -> R {
|
||||||
|
self.inner.with(|inner| {
|
||||||
|
(callback)(
|
||||||
|
inner
|
||||||
|
.as_ref()
|
||||||
|
.expect("an allocator must be installed in the global allocator proxy"),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_with<R>(&self, callback: impl FnOnce(&mut AllocationTracer) -> R) -> R {
|
||||||
|
self.tracer
|
||||||
|
.lock(|tracer| (callback)(&mut tracer.borrow_mut()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<T> GlobalAlloc for TracingAllocator<T>
|
||||||
|
where
|
||||||
|
T: GlobalAlloc,
|
||||||
|
{
|
||||||
|
unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
|
||||||
|
let bt = Backtrace::capture();
|
||||||
|
let ptr = self.with_inner(|inner| unsafe { inner.alloc(layout) });
|
||||||
|
self.update_with(|tracer| tracer.alloc(bt, ptr, layout.size()));
|
||||||
|
ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn alloc_zeroed(&self, layout: core::alloc::Layout) -> *mut u8 {
|
||||||
|
let bt = Backtrace::capture();
|
||||||
|
let ptr = self.with_inner(|inner| unsafe { inner.alloc_zeroed(layout) });
|
||||||
|
self.update_with(|tracer| tracer.alloc(bt, ptr, layout.size()));
|
||||||
|
ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn realloc(
|
||||||
|
&self,
|
||||||
|
ptr_old: *mut u8,
|
||||||
|
layout: core::alloc::Layout,
|
||||||
|
new_size: usize,
|
||||||
|
) -> *mut u8 {
|
||||||
|
let ptr_new =
|
||||||
|
self.with_inner(|inner| unsafe { inner.realloc(ptr_old, layout, new_size) });
|
||||||
|
self.update_with(|tracer| tracer.realloc(ptr_old, ptr_new, layout.size(), new_size));
|
||||||
|
ptr_new
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn dealloc(&self, ptr: *mut u8, layout: core::alloc::Layout) {
|
||||||
|
self.update_with(|tracer| tracer.dealloc(ptr, layout.size()));
|
||||||
|
self.with_inner(|inner| unsafe { inner.dealloc(ptr, layout) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[global_allocator]
|
||||||
|
static PROXY: TracingAllocator<EspHeap> = TracingAllocator::new();
|
||||||
|
|
||||||
|
pub fn install_iram_allocator_proxy() {
|
||||||
|
PROXY.inner.with(|inner| {
|
||||||
|
*inner = Some(&esp_alloc::HEAP);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn report_stats() {
|
||||||
|
let AllocationTracer {
|
||||||
|
bt_to_stats,
|
||||||
|
ptr_to_bt,
|
||||||
|
} = PROXY.tracer.lock(|tracer| tracer.borrow().clone());
|
||||||
|
// Wrapped in `Option` because of the `Default` requirement.
|
||||||
|
let mut sorted = ArrayVec::<[Option<(BacktraceWrapper, Reverse<Stats>)>; 5]>::new();
|
||||||
|
let bt_to_stats_len = bt_to_stats.len();
|
||||||
|
|
||||||
|
for (key, value) in bt_to_stats {
|
||||||
|
// Reverse ordering of stats because we are interested in the largest.
|
||||||
|
let value_rev = Reverse(value);
|
||||||
|
if let Some((_, value_last)) = sorted.last().and_then(|last| last.as_ref())
|
||||||
|
&& &value_rev >= value_last
|
||||||
|
&& sorted.len() >= sorted.capacity()
|
||||||
|
{
|
||||||
|
// This stat is not large enough to be inserted.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let index = match sorted.binary_search_by_key(&Some(&value_rev), |item| {
|
||||||
|
item.as_ref().map(|(_, current_value)| current_value)
|
||||||
|
}) {
|
||||||
|
Ok(index) => index,
|
||||||
|
Err(index) => index,
|
||||||
|
};
|
||||||
|
if sorted.len() >= sorted.capacity() {
|
||||||
|
assert!(
|
||||||
|
index < sorted.len(),
|
||||||
|
"the stat should be large enough to be inserted not at the end of the list"
|
||||||
|
);
|
||||||
|
let _ = sorted.pop().unwrap();
|
||||||
|
}
|
||||||
|
sorted.insert(index, Some((key, value_rev)));
|
||||||
|
}
|
||||||
|
|
||||||
|
warn!("Largest allocations in global allocator:");
|
||||||
|
|
||||||
|
for (index, (key, value)) in sorted.into_iter().map(Option::unwrap).enumerate() {
|
||||||
|
warn!("{}. {}\n{:#?}", index + 1, key, value.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
warn!("bt_to_stats.len() = {}", bt_to_stats_len);
|
||||||
|
warn!("ptr_to_bt.len() = {}", ptr_to_bt.len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
ffi::{alloc::__spre_free, crypto::ACTIVE_ENCRYPTED_USER_KEY},
|
ffi::{alloc::__spre_free, crypto::ACTIVE_ENCRYPTED_USER_KEY},
|
||||||
proxy::OUTPUT_STRING_CHANNEL,
|
proxy::OUTPUT_STRING_CHANNEL,
|
||||||
|
ram::PsramAllocator,
|
||||||
ui::{
|
ui::{
|
||||||
backend::SlintBackend,
|
backend::SlintBackend,
|
||||||
messages::{
|
messages::{
|
||||||
|
|
@ -130,7 +131,7 @@ pub async fn run_renderer_task(backend: SlintBackend, flash_part_acid: Partition
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
window: AppWindow,
|
window: AppWindow,
|
||||||
db: Rc<AcidDatabase>,
|
db: Rc<AcidDatabase, PsramAllocator>,
|
||||||
users: SpectreUsersConfig,
|
users: SpectreUsersConfig,
|
||||||
/// Currently active view.
|
/// Currently active view.
|
||||||
view: AppState,
|
view: AppState,
|
||||||
|
|
@ -142,20 +143,23 @@ struct State {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
async fn new(db: AcidDatabase, main: AppWindow) -> Rc<RefCell<Self>> {
|
async fn new(db: AcidDatabase, main: AppWindow) -> Rc<RefCell<Self>, PsramAllocator> {
|
||||||
let users = Self::load_users(&db).await;
|
let users = Self::load_users(&db).await;
|
||||||
let usernames = users.users.clone().map(|user| user.username);
|
let usernames = users.users.clone().map(|user| user.username);
|
||||||
|
|
||||||
let state = Rc::new(RefCell::new(State {
|
let state = Rc::new_in(
|
||||||
window: main.clone_strong(),
|
RefCell::new(State {
|
||||||
users,
|
window: main.clone_strong(),
|
||||||
db: Rc::new(db),
|
users,
|
||||||
view: AppState::Login,
|
db: Rc::new_in(db, &PSRAM_ALLOCATOR),
|
||||||
state_login: Default::default(),
|
view: AppState::Login,
|
||||||
state_users: Default::default(),
|
state_login: Default::default(),
|
||||||
state_user_edit: Default::default(),
|
state_users: Default::default(),
|
||||||
state_user_sites: Default::default(),
|
state_user_edit: Default::default(),
|
||||||
}));
|
state_user_sites: Default::default(),
|
||||||
|
}),
|
||||||
|
&PSRAM_ALLOCATOR,
|
||||||
|
);
|
||||||
|
|
||||||
main.on_enter_view({
|
main.on_enter_view({
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
|
|
@ -332,7 +336,10 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_callback_message(state_rc: &Rc<RefCell<State>>, message: CallbackMessage) {
|
fn process_callback_message(
|
||||||
|
state_rc: &Rc<RefCell<State>, PsramAllocator>,
|
||||||
|
message: CallbackMessage,
|
||||||
|
) {
|
||||||
let view = state_rc.borrow().view;
|
let view = state_rc.borrow().view;
|
||||||
match view {
|
match view {
|
||||||
AppState::Login => StateLogin::process_callback_message(state_rc, message),
|
AppState::Login => StateLogin::process_callback_message(state_rc, message),
|
||||||
|
|
@ -382,14 +389,21 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait AppViewTrait {
|
trait AppViewTrait {
|
||||||
fn process_callback_message(_state_rc: &Rc<RefCell<State>>, _message: CallbackMessage) {}
|
fn process_callback_message(
|
||||||
|
_state_rc: &Rc<RefCell<State>, PsramAllocator>,
|
||||||
|
_message: CallbackMessage,
|
||||||
|
) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct StateLogin {}
|
struct StateLogin {}
|
||||||
|
|
||||||
impl AppViewTrait for StateLogin {
|
impl AppViewTrait for StateLogin {
|
||||||
fn process_callback_message(state_rc: &Rc<RefCell<State>>, message: CallbackMessage) {
|
fn process_callback_message(
|
||||||
|
state_rc: &Rc<RefCell<State>, PsramAllocator>,
|
||||||
|
message: CallbackMessage,
|
||||||
|
) {
|
||||||
let mut state = state_rc.borrow_mut();
|
let mut state = state_rc.borrow_mut();
|
||||||
match message {
|
match message {
|
||||||
CallbackMessage::Login(CallbackMessageLogin::PwAccepted {
|
CallbackMessage::Login(CallbackMessageLogin::PwAccepted {
|
||||||
|
|
@ -542,7 +556,10 @@ impl AppViewTrait for StateLogin {
|
||||||
struct StateUsers {}
|
struct StateUsers {}
|
||||||
|
|
||||||
impl AppViewTrait for StateUsers {
|
impl AppViewTrait for StateUsers {
|
||||||
fn process_callback_message(state_rc: &Rc<RefCell<State>>, message: CallbackMessage) {
|
fn process_callback_message(
|
||||||
|
state_rc: &Rc<RefCell<State>, PsramAllocator>,
|
||||||
|
message: CallbackMessage,
|
||||||
|
) {
|
||||||
let mut state = state_rc.borrow_mut();
|
let mut state = state_rc.borrow_mut();
|
||||||
match message {
|
match message {
|
||||||
CallbackMessage::Escape => {
|
CallbackMessage::Escape => {
|
||||||
|
|
@ -572,7 +589,10 @@ struct StateUserEdit {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppViewTrait for StateUserEdit {
|
impl AppViewTrait for StateUserEdit {
|
||||||
fn process_callback_message(state_rc: &Rc<RefCell<State>>, message: CallbackMessage) {
|
fn process_callback_message(
|
||||||
|
state_rc: &Rc<RefCell<State>, PsramAllocator>,
|
||||||
|
message: CallbackMessage,
|
||||||
|
) {
|
||||||
let state = state_rc.clone();
|
let state = state_rc.clone();
|
||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
match message {
|
match message {
|
||||||
|
|
@ -722,7 +742,10 @@ struct StateUserSites {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppViewTrait for StateUserSites {
|
impl AppViewTrait for StateUserSites {
|
||||||
fn process_callback_message(state_rc: &Rc<RefCell<State>>, message: CallbackMessage) {
|
fn process_callback_message(
|
||||||
|
state_rc: &Rc<RefCell<State>, PsramAllocator>,
|
||||||
|
message: CallbackMessage,
|
||||||
|
) {
|
||||||
let state = state_rc.clone();
|
let state = state_rc.clone();
|
||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
match message {
|
match message {
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ pub const fn get_file_name(path: &str) -> &str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
pub trait MutexExt<M, T> {
|
pub trait MutexExt<M, T> {
|
||||||
type Guard<'a>
|
type Guard<'a>
|
||||||
where
|
where
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue