WIP2
This commit is contained in:
parent
561be96f24
commit
352e52852f
|
|
@ -7,7 +7,7 @@ target = "xtensa-esp32s3-none-elf"
|
|||
rustflags = [
|
||||
# Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.)
|
||||
# NOTE: May negatively impact performance of produced code
|
||||
"-C", "force-frame-pointers", "-C", "link-arg=-Wl,--wrap=strncmp",
|
||||
"-C", "force-frame-pointers",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
5
firmware2/Cargo.lock
generated
5
firmware2/Cargo.lock
generated
|
|
@ -20,6 +20,7 @@ dependencies = [
|
|||
"embedded-cli",
|
||||
"embedded-io 0.6.1",
|
||||
"embuild",
|
||||
"enumset",
|
||||
"esp-alloc",
|
||||
"esp-backtrace",
|
||||
"esp-bootloader-esp-idf",
|
||||
|
|
@ -6915,9 +6916,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tinyrlibc"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d07d242693682e46801cb0186c583858bce022f698401b3f04bbd729c9a87e7"
|
||||
checksum = "9af8adde15cc59c61328c5d709b41b8464522a733033584d33def687b26bd009"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ debug = []
|
|||
trace = []
|
||||
# Development profiles
|
||||
develop = ["limit-fps", "alt-log"]
|
||||
develop-usb = ["limit-fps", "usb-log", "no-usb"]
|
||||
probe = ["limit-fps", "rtt-log", "no-usb"]
|
||||
develop-usb = ["limit-fps", "usb-log", "no-usb", "ble"]
|
||||
probe = ["limit-fps", "rtt-log", "no-usb", "ble"]
|
||||
|
||||
[dependencies]
|
||||
rmk = { version = "0.8.2", default-features = false, features = [
|
||||
|
|
@ -54,7 +54,7 @@ esp-backtrace = { version = "0.18", default-features = false, features = [
|
|||
] }
|
||||
esp-hal = { version = "1.0", features = ["esp32s3", "unstable", "psram", "log-04"] }
|
||||
esp-storage = { version = "0.8.0", features = ["esp32s3"] }
|
||||
esp-alloc = { version = "0.9.0" }
|
||||
esp-alloc = { version = "0.9.0", features = ["nightly"] }
|
||||
esp-println = { version = "0.16.0", features = ["esp32s3", "log-04"] }
|
||||
esp-radio = { version = "0.17", features = ["esp32s3", "unstable", "ble"] }
|
||||
esp-rtos = { version = "0.2", features = ["esp32s3", "esp-radio", "embassy"] }
|
||||
|
|
@ -79,6 +79,7 @@ panic-rtt-target = { version = "0.2.0", optional = true }
|
|||
embedded-cli = { version = "0.2.1", default-features = false, features = ["help", "macros"] }
|
||||
embedded-io = "0.6.1"
|
||||
mutually_exclusive_features = "0.1.0"
|
||||
enumset = "1.1.10"
|
||||
|
||||
[build-dependencies]
|
||||
xz2 = "0.1.7"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,33 @@
|
|||
# ACID firmware
|
||||
|
||||
## Building
|
||||
|
||||
### Compiling libxkbcommon
|
||||
|
||||
This needs to be done on Linux or in WSL.
|
||||
meson.build needs to be changed such that `pkgconfig.generate` is called with the `variables` field embedded directly, for some reason:
|
||||
|
||||
```meson
|
||||
variables: [
|
||||
f'xkb_root=@XKB_CONFIG_ROOT@',
|
||||
f'xkb_extra_path=@XKB_CONFIG_EXTRA_PATH@',
|
||||
],
|
||||
```
|
||||
|
||||
Then, the tests, fuzzes and benches need to be commented out.
|
||||
Afterwards, the following command should succeed in building the static library in debug mode:
|
||||
|
||||
```sh
|
||||
meson setup build-debug -Denable-x11=false -Dxkb-config-root=/usr/share/X11/xkb -Dx-locale-root=/usr/share/X11/locale -Denable-wayland=false --cross-file cross-esp32s3.txt -Denable-xkbregistry=false -Denable-docs=false -Denable-tools=false --wipe --buildtype=debug
|
||||
meson compile -C build-debug
|
||||
```
|
||||
|
||||
Afterwards, a static library with redefined externally-linked symbols needs to be generated:
|
||||
|
||||
```
|
||||
path/to/root/libxkbcommon-redefine-syms.sh build-debug/libxkbcommon{,_redefined_syms}.a
|
||||
```
|
||||
|
||||
# esp32s3 BLE example
|
||||
|
||||
To run this example, you should have latest Rust in **esp** channel installed. The full instruction of installing esp Rust toolchain can be found [here](https://docs.esp-rs.org/book/installation/index.html).
|
||||
|
|
@ -18,7 +48,7 @@ cargo +esp run --release
|
|||
If everything is good, you'll see the log as the following:
|
||||
|
||||
```shell
|
||||
cargo run --release
|
||||
cargo run --release
|
||||
Compiling ...
|
||||
...
|
||||
...
|
||||
|
|
@ -62,4 +92,4 @@ cargo install --git https://github.com/bjoernQ/espsegs
|
|||
|
||||
# Check all segments
|
||||
espsegs target/xtensa-esp32s3-none-elf/release/rmk-esp32s3 --chip esp32s3
|
||||
```
|
||||
```
|
||||
|
|
|
|||
|
|
@ -35,10 +35,12 @@ fn main() {
|
|||
println!(r#"cargo:rustc-link-search=native=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug"#);
|
||||
|
||||
// 2. Link the static library (strip the 'lib' prefix and '.a' extension)
|
||||
println!("cargo:rustc-link-lib=static=xkbcommon");
|
||||
// println!("cargo:rustc-link-lib=static=xkbcommon");
|
||||
println!("cargo:rustc-link-lib=static=xkbcommon_redefined_syms");
|
||||
|
||||
// 3. Re-run if build.rs or the library changes
|
||||
println!(r#"cargo:rerun-if-changed=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug\libxkbcommon.a"#);
|
||||
// println!(r#"cargo:rerun-if-changed=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug\libxkbcommon.a"#);
|
||||
println!(r#"cargo:rerun-if-changed=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug\libxkbcommon_redefined_syms.a"#);
|
||||
|
||||
let slint_config = CompilerConfiguration::new()
|
||||
// .with_scale_factor(4.0)
|
||||
|
|
|
|||
39
firmware2/cross-esp32s3.txt
Normal file
39
firmware2/cross-esp32s3.txt
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
[binaries]
|
||||
c = 'xtensa-esp32s3-elf-gcc'
|
||||
cpp = 'xtensa-esp32s3-elf-g++'
|
||||
ar = 'xtensa-esp32s3-elf-ar'
|
||||
strip = 'xtensa-esp32s3-elf-strip'
|
||||
|
||||
[build_machine]
|
||||
system = 'linux'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
|
||||
[host_machine]
|
||||
system = 'bare-metal' # Crucial: prevents Meson from assuming a POSIX environment
|
||||
cpu_family = 'xtensa'
|
||||
cpu = 'esp32s3'
|
||||
endian = 'little'
|
||||
|
||||
[built-in options]
|
||||
c_args = [
|
||||
'-fdebug-prefix-map=@GLOBAL_SOURCE_ROOT@=C:/Users/Limeth/workspace/c/libxkbcommon-linux',
|
||||
'-ffreestanding',
|
||||
'-fno-builtin',
|
||||
'-mlongcalls',
|
||||
'-mfix-esp32-psram-cache-issue',
|
||||
# Manually define the missing inttypes.h macros
|
||||
'-DPRId64="lld"',
|
||||
'-DPRIu64="llu"',
|
||||
'-DPRIi64="lli"',
|
||||
'-DPRId32="d"',
|
||||
'-DPRIu32="u"',
|
||||
'-DPRIx64="llx"'
|
||||
]
|
||||
c_link_args = [
|
||||
'-nostdlib',
|
||||
'-static'
|
||||
]
|
||||
# Ensure we only build static libraries for bare-metal
|
||||
default_library = 'static'
|
||||
1114
firmware2/keymaps/cz-small-test.xkb
Normal file
1114
firmware2/keymaps/cz-small-test.xkb
Normal file
File diff suppressed because it is too large
Load diff
28
firmware2/libxkbcommon-redefine-syms.sh
Normal file
28
firmware2/libxkbcommon-redefine-syms.sh
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
INPUT_LIB=$1
|
||||
OUTPUT_LIB=$2
|
||||
PREFIX="__xkbc_"
|
||||
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: $0 <input_lib.a> <output_lib.a>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Redefining symbols from $INPUT_LIB into $OUTPUT_LIB..."
|
||||
|
||||
# We use <(...) to stream the symbol map directly into objcopy
|
||||
# xtensa-esp-elf-objcopy --redefine-syms=<(
|
||||
# xtensa-esp-elf-nm -u "$INPUT_LIB" |
|
||||
# awk '{print $NF}' |
|
||||
# sort -u |
|
||||
# awk -v p="$PREFIX" '{print $1 " " p $1}'
|
||||
# ) "$INPUT_LIB" "$OUTPUT_LIB"
|
||||
|
||||
xtensa-esp-elf-objcopy --redefine-syms=<(
|
||||
comm -23 \
|
||||
<(xtensa-esp-elf-nm -u "$INPUT_LIB" | awk '{print $NF}' | sort -u) \
|
||||
<(xtensa-esp-elf-nm --defined-only "$INPUT_LIB" | awk '{print $NF}' | sort -u) | \
|
||||
awk -v p="$PREFIX" '{print $1 " " p $1}'
|
||||
) "$INPUT_LIB" "$OUTPUT_LIB"
|
||||
|
||||
echo "Done! Prefixed all externally linked symbols with $PREFIX."
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
#![allow(unused)]
|
||||
|
||||
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::{null, null_mut}};
|
||||
|
||||
unsafe extern "C" {
|
||||
fn malloc(size: c_size_t) -> *mut c_void;
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn strpbrk(s: *const c_char, accept: *const c_char) -> *mut c_char {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
type c_intmax_t = c_longlong;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn imaxabs(j: c_intmax_t) -> c_intmax_t {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn eaccess(pathname: *const c_char, mode: c_int ) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn vasprintf(strp: *mut *mut c_char, fmt: *const c_char, ap: VaList) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
type stat = c_void; // Not implemented
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn stat(path: *const c_char, buf: *mut stat) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn __errno() -> *mut c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn strerror(errnum: c_int) -> *mut c_char {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
type DIR = c_void; // Not implemented
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
type dirent = c_void; // Not implemented
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn opendir(name: *const c_char) -> *mut DIR {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn readdir(dirp: *mut DIR) -> *mut dirent {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn closedir(dirp: *mut DIR) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn qsort(
|
||||
base: *mut c_void,
|
||||
num: c_size_t,
|
||||
size: c_size_t,
|
||||
compar: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn __getreent() -> *mut c_void /*struct _reent*/ {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
enum FILE {}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn fprintf(
|
||||
stream: *mut FILE,
|
||||
format: *const c_char,
|
||||
...
|
||||
) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn vfprintf(stream: *mut FILE, format: *const c_char, ap: VaList) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn strtol(nptr: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_long {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn secure_getenv(name: *const c_char) -> *mut c_char {
|
||||
unsafe { getenv(name) }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn getenv(name: *const c_char) -> *mut c_char {
|
||||
null_mut()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn fseek(
|
||||
stream: *mut FILE,
|
||||
offset: c_long,
|
||||
whence: c_int,
|
||||
) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn ftell(stream: *mut FILE) -> c_long {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn fread(
|
||||
ptr: *mut c_void,
|
||||
size: c_size_t,
|
||||
nobj: c_size_t,
|
||||
stream: *mut FILE,
|
||||
) -> c_size_t {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn open(
|
||||
path: *const c_char,
|
||||
oflag: c_int,
|
||||
...
|
||||
) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn close(fd: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn fdopen(
|
||||
fd: c_int,
|
||||
mode: *const c_char,
|
||||
) -> *mut FILE {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn strndup(
|
||||
s: *const c_char,
|
||||
n: c_size_t,
|
||||
) -> *mut c_char {
|
||||
let len = unsafe { strnlen(s, n) };
|
||||
let new = unsafe { malloc(len + 1) } as *mut c_char;
|
||||
|
||||
if new.is_null() {
|
||||
return null_mut();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
*new.add(len) = b'\0';
|
||||
|
||||
memcpy(new as *mut c_void, s as *const c_void, len) as *mut c_char
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn labs(i: c_long) -> c_long {
|
||||
i.abs()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn memcpy(dest: *mut c_void, src: *const c_void, n: c_size_t) -> *mut c_void {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn strnlen(s: *const c_char, maxlen: c_size_t) -> c_size_t {
|
||||
let found: *const c_char = unsafe { memchr(s as *const c_void, b'\0' as c_int, maxlen) } as *const c_char;
|
||||
if !found.is_null() { unsafe { found.offset_from(s) as c_size_t } } else { maxlen }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn memchr(s: *const c_void, c: c_int, n: c_size_t) -> *mut c_void {
|
||||
let mut s = s as *const c_uchar;
|
||||
let c = c as c_uchar;
|
||||
|
||||
for _ in 0..n {
|
||||
unsafe {
|
||||
if *s == c {
|
||||
return s as *mut c_void;
|
||||
}
|
||||
|
||||
s = s.add(1);
|
||||
}
|
||||
}
|
||||
|
||||
null_mut()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn __wrap_strncmp(
|
||||
s1: *const c_char,
|
||||
s2: *const c_char,
|
||||
n: c_size_t,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
for i in 0..n as isize {
|
||||
let s1_i = s1.offset(i);
|
||||
let s2_i = s2.offset(i);
|
||||
|
||||
let val = *s1_i as c_int - *s2_i as c_int;
|
||||
if val != 0 || *s1_i == 0 {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
}
|
||||
104
firmware2/src/ffi/alloc.rs
Normal file
104
firmware2/src/ffi/alloc.rs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut};
|
||||
|
||||
use core::alloc::GlobalAlloc;
|
||||
|
||||
use enumset::EnumSet;
|
||||
use esp_alloc::EspHeap;
|
||||
|
||||
// Here we select the allocator to use for libxkbcommon.
|
||||
static XKBC_ALLOCATOR: &EspHeap = &crate::PSRAM_ALLOCATOR;
|
||||
|
||||
// Implementation based on esp-alloc's `compat` feature.
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_malloc(size: c_size_t) -> *mut c_void {
|
||||
unsafe { malloc_with_caps(size, EnumSet::empty()) as *mut _ }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_calloc(
|
||||
number: c_size_t,
|
||||
size: c_size_t,
|
||||
) -> *mut c_void {
|
||||
let total_size = number as usize * size;
|
||||
unsafe {
|
||||
let ptr = __xkbc_malloc(total_size) as *mut u8;
|
||||
|
||||
if !ptr.is_null() {
|
||||
for i in 0..total_size as isize {
|
||||
ptr.offset(i).write_volatile(0);
|
||||
}
|
||||
}
|
||||
|
||||
ptr as *mut _
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_realloc(
|
||||
ptr: *mut c_void,
|
||||
new_size: c_size_t,
|
||||
) -> *mut c_void {
|
||||
unsafe { realloc_with_caps(ptr as *mut _, new_size, EnumSet::empty()) as *mut _ }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_free(ptr: *mut c_void) {
|
||||
if ptr.is_null() {
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let ptr = ptr.offset(-4);
|
||||
let total_size = *(ptr as *const usize);
|
||||
|
||||
XKBC_ALLOCATOR.dealloc(
|
||||
ptr as *mut u8,
|
||||
core::alloc::Layout::from_size_align_unchecked(total_size, 4),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn malloc_with_caps(
|
||||
size: usize,
|
||||
caps: EnumSet<crate::MemoryCapability>,
|
||||
) -> *mut u8 {
|
||||
let total_size = size + 4;
|
||||
|
||||
unsafe {
|
||||
let ptr = XKBC_ALLOCATOR.alloc_caps(
|
||||
caps,
|
||||
core::alloc::Layout::from_size_align_unchecked(total_size, 4),
|
||||
);
|
||||
|
||||
if ptr.is_null() {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
*(ptr as *mut usize) = total_size;
|
||||
ptr.offset(4)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn realloc_with_caps(
|
||||
ptr: *mut u8,
|
||||
new_size: usize,
|
||||
caps: enumset::EnumSet<crate::MemoryCapability>,
|
||||
) -> *mut u8 {
|
||||
unsafe extern "C" {
|
||||
fn memcpy(d: *mut u8, s: *const u8, l: usize);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let p = malloc_with_caps(new_size, caps);
|
||||
if !p.is_null() && !ptr.is_null() {
|
||||
let len = usize::min(
|
||||
(ptr as *const u32).sub(1).read_volatile() as usize,
|
||||
new_size,
|
||||
);
|
||||
memcpy(p, ptr, len);
|
||||
__xkbc_free(ptr as *mut _);
|
||||
}
|
||||
p
|
||||
}
|
||||
}
|
||||
12
firmware2/src/ffi/gcc_runtime.rs
Normal file
12
firmware2/src/ffi/gcc_runtime.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
//! https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gccint/Libgcc.html
|
||||
|
||||
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut};
|
||||
|
||||
unsafe extern "C" {
|
||||
fn __divdi3(a: c_long, b: c_long) -> c_long;
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc___divdi3(a: c_long, b: c_long) -> c_long {
|
||||
unsafe { __divdi3(a, b) }
|
||||
}
|
||||
25
firmware2/src/ffi/inout/dir.rs
Normal file
25
firmware2/src/ffi/inout/dir.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum DIR {}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
pub struct dirent {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_opendir(name: *const c_char) -> *mut DIR {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_readdir(dirp: *mut DIR) -> *mut dirent {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_closedir(dirp: *mut DIR) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
9
firmware2/src/ffi/inout/file.rs
Normal file
9
firmware2/src/ffi/inout/file.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut};
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub enum FILE {}
|
||||
|
||||
pub const STDIN: *mut FILE = 0 as _;
|
||||
pub const STDOUT: *mut FILE = 1 as _;
|
||||
pub const STDERR: *mut FILE = 2 as _;
|
||||
93
firmware2/src/ffi/inout/mod.rs
Normal file
93
firmware2/src/ffi/inout/mod.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
//! This would've been called `io`, but rust-analyzer refuses to see
|
||||
//! the submodules of this module when it's named `io`.
|
||||
|
||||
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut};
|
||||
|
||||
use log::info;
|
||||
|
||||
pub mod file;
|
||||
pub mod dir;
|
||||
|
||||
pub use file::*;
|
||||
pub use dir::*;
|
||||
|
||||
// File management
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_fopen(
|
||||
filename: *const c_char,
|
||||
mode: *const c_char,
|
||||
) -> *mut FILE {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_fclose(file: *mut FILE) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_fseek(
|
||||
stream: *mut FILE,
|
||||
offset: c_long,
|
||||
whence: c_int,
|
||||
) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_ftell(stream: *mut FILE) -> c_long {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_fread(
|
||||
ptr: *mut c_void,
|
||||
size: c_size_t,
|
||||
nobj: c_size_t,
|
||||
stream: *mut FILE,
|
||||
) -> c_size_t {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// Printing
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_fprintf(
|
||||
stream: *mut FILE,
|
||||
format: *const c_char,
|
||||
mut args: ...
|
||||
) -> c_int {
|
||||
unsafe { __xkbc_vfprintf(stream, format, args.as_va_list()) }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_vfprintf(stream: *mut FILE, format: *const c_char, ap: VaList) -> c_int {
|
||||
if stream == STDOUT || stream == STDERR {
|
||||
let string = ::alloc::format!("vfprintf({:?}, {:?}, {:?})", stream, format, ap);
|
||||
info!("{}", string);
|
||||
string.len() as c_int
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_vasprintf(strp: *mut *mut c_char, fmt: *const c_char, ap: VaList) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_vsnprintf(string: *mut c_char, size: c_size_t, format: *const c_char, ap: VaList) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_snprintf(
|
||||
s: *mut c_char,
|
||||
n: c_size_t,
|
||||
format: *const c_char,
|
||||
...
|
||||
) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
130
firmware2/src/ffi/mod.rs
Normal file
130
firmware2/src/ffi/mod.rs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut};
|
||||
|
||||
use alloc::__xkbc_malloc;
|
||||
use inout::{FILE, STDERR, STDIN, STDOUT};
|
||||
use log::info;
|
||||
|
||||
pub mod alloc;
|
||||
pub mod string;
|
||||
pub mod inout;
|
||||
pub mod gcc_runtime;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type c_intmax_t = c_longlong;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_imaxabs(j: c_intmax_t) -> c_intmax_t {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_eaccess(pathname: *const c_char, mode: c_int ) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
type stat = c_void; // Not implemented
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_stat(path: *const c_char, buf: *mut stat) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc___errno() -> *mut c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_qsort(
|
||||
base: *mut c_void,
|
||||
num: c_size_t,
|
||||
size: c_size_t,
|
||||
compar: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
|
||||
) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// An incomplete representation of Newlib's `struct _reent`.
|
||||
/// https://github.com/bminor/newlib/blob/b41e3b652c4215556a62a2f47e8f8f11553fa550/newlib/libc/include/sys/reent.h#L580
|
||||
#[repr(C)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct _reent {
|
||||
_errno: c_int,
|
||||
_stdin: *mut FILE,
|
||||
_stdout: *mut FILE,
|
||||
_stderr: *mut FILE,
|
||||
// Rest unimplemented
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc___getreent() -> *mut _reent {
|
||||
static mut REENT: [_reent; 2] = [_reent {
|
||||
_errno: 0,
|
||||
_stdin: STDIN,
|
||||
_stdout: STDOUT,
|
||||
_stderr: STDERR,
|
||||
}; 2];
|
||||
|
||||
unsafe {
|
||||
let reent = &mut REENT[esp_hal::system::Cpu::current() as usize];
|
||||
reent as *mut _reent
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_secure_getenv(name: *const c_char) -> *mut c_char {
|
||||
unsafe { __xkbc_getenv(name) }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_getenv(name: *const c_char) -> *mut c_char {
|
||||
null_mut()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_open(
|
||||
path: *const c_char,
|
||||
oflag: c_int,
|
||||
...
|
||||
) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_fstat(fildes: c_int, buf: *mut stat) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_close(fd: c_int) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_fdopen(
|
||||
fd: c_int,
|
||||
mode: *const c_char,
|
||||
) -> *mut FILE {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_labs(i: c_long) -> c_long {
|
||||
i.abs()
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
fn __assert_func(file: *const c_char, line: c_int, function: *const c_char, failedExpression: *const c_char);
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc___assert_func(file: *const c_char, line: c_int, function: *const c_char, failed_expression: *const c_char) {
|
||||
unsafe { __assert_func(file, line, function, failed_expression); }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_atoi(s: *const c_char) -> c_int {
|
||||
todo!()
|
||||
}
|
||||
193
firmware2/src/ffi/string.rs
Normal file
193
firmware2/src/ffi/string.rs
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut};
|
||||
|
||||
use super::alloc::__xkbc_malloc;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_memset(
|
||||
dest_original: *mut c_void,
|
||||
c: c_int,
|
||||
n: c_size_t,
|
||||
) -> *mut c_void {
|
||||
if dest_original == null_mut() {
|
||||
if n > 0 {
|
||||
panic!("Attempted to memset a nullptr.");
|
||||
} else {
|
||||
return null_mut();
|
||||
}
|
||||
}
|
||||
|
||||
let mut dest = dest_original as *mut u8;
|
||||
let c = c as u8;
|
||||
for _ in 0..n {
|
||||
unsafe {
|
||||
*dest = c;
|
||||
dest = dest.add(1);
|
||||
}
|
||||
}
|
||||
|
||||
dest_original
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_memmove(
|
||||
dst: *mut c_void,
|
||||
src: *const c_void,
|
||||
count: c_size_t,
|
||||
) -> *mut c_void {
|
||||
unsafe { core::ptr::copy(src, dst, count) };
|
||||
dst
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_memcpy(dst: *mut c_void, src: *const c_void, count: c_size_t) -> *mut c_void {
|
||||
unsafe { core::ptr::copy_nonoverlapping(src, dst, count); }
|
||||
dst
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_memchr(s: *const c_void, c: c_int, n: c_size_t) -> *mut c_void {
|
||||
let mut s = s as *const c_uchar;
|
||||
let c = c as c_uchar;
|
||||
|
||||
for _ in 0..n {
|
||||
unsafe {
|
||||
if *s == c {
|
||||
return s as *mut c_void;
|
||||
}
|
||||
|
||||
s = s.add(1);
|
||||
}
|
||||
}
|
||||
|
||||
null_mut()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_memcmp(
|
||||
mut s1: *const c_char,
|
||||
mut s2: *const c_char,
|
||||
n: c_size_t,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
for i in 0..n as isize {
|
||||
let s1_i = s1.offset(i);
|
||||
let s2_i = s2.offset(i);
|
||||
let val = *s1_i as c_int - *s2_i as c_int;
|
||||
|
||||
if val != 0 {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_strpbrk(s: *const c_char, accept: *const c_char) -> *mut c_char {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_strerror(errnum: c_int) -> *mut c_char {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_strdup(string: *const c_char) -> *mut c_char {
|
||||
strndup_inner(string, unsafe { __xkbc_strlen(string) })
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_strndup(
|
||||
string: *const c_char,
|
||||
max_len: c_size_t,
|
||||
) -> *mut c_char {
|
||||
strndup_inner(string, unsafe { __xkbc_strnlen(string, max_len) })
|
||||
}
|
||||
|
||||
fn strndup_inner(string: *const c_char, computed_len: c_size_t) -> *mut c_char {
|
||||
let new = unsafe { __xkbc_malloc(computed_len + 1) } as *mut c_char;
|
||||
|
||||
if new.is_null() {
|
||||
return null_mut();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
*new.add(computed_len) = b'\0';
|
||||
|
||||
__xkbc_memcpy(new as *mut c_void, string as *const c_void, computed_len) as *mut c_char
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_strlen(mut s: *const c_char) -> c_size_t {
|
||||
let mut result = 0;
|
||||
unsafe {
|
||||
while *s != 0 {
|
||||
s = s.offset(1);
|
||||
result += 1;
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_strnlen(s: *const c_char, maxlen: c_size_t) -> c_size_t {
|
||||
let found: *const c_char = unsafe { __xkbc_memchr(s as *const c_void, b'\0' as c_int, maxlen) } as *const c_char;
|
||||
if !found.is_null() { unsafe { found.offset_from(s) as c_size_t } } else { maxlen }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_strncmp(
|
||||
s1: *const c_char,
|
||||
s2: *const c_char,
|
||||
n: c_size_t,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
for i in 0..n as isize {
|
||||
let s1_i = s1.offset(i);
|
||||
let s2_i = s2.offset(i);
|
||||
let val = *s1_i as c_int - *s2_i as c_int;
|
||||
|
||||
if val != 0 || *s1_i == 0 {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_strchr(
|
||||
cs: *const c_char,
|
||||
c: c_int,
|
||||
) -> *mut c_char {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_strcmp(
|
||||
s1: *const c_char,
|
||||
s2: *const c_char,
|
||||
) -> c_int {
|
||||
unsafe {
|
||||
for i in 0_isize.. {
|
||||
let s1_i = s1.offset(i);
|
||||
let s2_i = s2.offset(i);
|
||||
let val = *s1_i as c_int - *s2_i as c_int;
|
||||
|
||||
if val != 0 || *s1_i == 0 {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __xkbc_strtol(nptr: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_long {
|
||||
todo!()
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
//! https://esp32.com/viewtopic.php?f=12&t=26793&start=20#p95677
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(macro_metavar_expr)]
|
||||
#![feature(c_variadic)]
|
||||
#![feature(c_size_t)]
|
||||
|
|
@ -17,9 +18,12 @@ extern crate alloc;
|
|||
use core::alloc::Layout;
|
||||
use core::cell::RefCell;
|
||||
use core::ffi::CStr;
|
||||
use core::slice;
|
||||
|
||||
use alloc::string::ToString;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::alloc::Allocator;
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::boxed::{self, Box};
|
||||
use alloc::vec::Vec;
|
||||
use alloc::vec;
|
||||
use bt_hci::controller::ExternalController;
|
||||
use cfg_if::cfg_if;
|
||||
|
|
@ -66,7 +70,6 @@ use slint::platform::software_renderer::Rgb565Pixel;
|
|||
use slint::ComponentHandle;
|
||||
use static_cell::StaticCell;
|
||||
use ui::AppWindow;
|
||||
use xkbcommon::xkb::{self, Keymap};
|
||||
use {esp_alloc as _, esp_backtrace as _};
|
||||
|
||||
use crate::matrix::IoeMatrix;
|
||||
|
|
@ -109,7 +112,7 @@ cfg_if! {
|
|||
|
||||
const FRAME_DURATION_MIN: Duration = Duration::from_millis(40); // 25 FPS
|
||||
|
||||
static PSRAM_ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
|
||||
pub static PSRAM_ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
|
||||
|
||||
/// Used to signal that MCU is ready to submit the framebuffer to the LCD.
|
||||
static SIGNAL_LCD_SUBMIT: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
||||
|
|
@ -153,6 +156,9 @@ async fn main(_spawner: Spawner) {
|
|||
let alt_uart_rx_task = async {};
|
||||
|
||||
// Use the internal DRAM as the heap.
|
||||
// TODO: Can we combine the regular link section with dram2?
|
||||
// esp_alloc::heap_allocator!(size: 80 * 1024);
|
||||
// esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 72 * 1024);
|
||||
esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 64 * 1024);
|
||||
info!("Heap initialized! {:#?}", esp_alloc::HEAP.stats());
|
||||
|
||||
|
|
@ -384,7 +390,10 @@ async fn main(_spawner: Spawner) {
|
|||
|
||||
info!("Second core started!");
|
||||
|
||||
let hid_report_proxy_task = async {};
|
||||
|
||||
let hid_report_proxy_task = {
|
||||
use xkbcommon::xkb::{self, Keymap};
|
||||
static KEYBOARD_REPORT_PROXY: Channel<CriticalSectionRawMutex, Report, 16> = Channel::new();
|
||||
|
||||
{
|
||||
|
|
@ -395,10 +404,21 @@ async fn main(_spawner: Spawner) {
|
|||
Timer::after_secs(1).await;
|
||||
info!("HID Report Proxy Task: Done waiting.");
|
||||
const KEYMAP_STRING: &str = include_str!("../keymaps/cz.xkb");
|
||||
let keymap_string_buffer = unsafe {
|
||||
let allocation = PSRAM_ALLOCATOR.alloc_caps(
|
||||
MemoryCapability::External.into(),
|
||||
Layout::from_size_align(KEYMAP_STRING.len(), 32).unwrap(),
|
||||
);
|
||||
let slice = str::from_utf8_unchecked_mut(slice::from_raw_parts_mut(allocation, KEYMAP_STRING.len()));
|
||||
|
||||
slice.as_bytes_mut().copy_from_slice(KEYMAP_STRING.as_bytes());
|
||||
|
||||
Box::from_raw_in(slice as *mut str, &PSRAM_ALLOCATOR)
|
||||
};
|
||||
info!("HID Report Proxy Task: test");
|
||||
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
|
||||
info!("HID Report Proxy Task: foo");
|
||||
let keymap = Keymap::new_from_string(&context, KEYMAP_STRING, xkb::KEYMAP_FORMAT_TEXT_V1, xkb::KEYMAP_COMPILE_NO_FLAGS).unwrap();
|
||||
let keymap = Keymap::new_from_string(&context, keymap_string_buffer, xkb::KEYMAP_FORMAT_TEXT_V1, xkb::KEYMAP_COMPILE_NO_FLAGS).unwrap();
|
||||
info!("HID Report Proxy Task: bar");
|
||||
|
||||
async {
|
||||
|
|
@ -472,6 +492,14 @@ impl Controller for UserController {
|
|||
|
||||
#[embassy_executor::task]
|
||||
async fn run_renderer_task(backend: SlintBackend) {
|
||||
// TODO: Disable rendering because it causes crashes in allocation
|
||||
loop {
|
||||
SIGNAL_LCD_SUBMIT.signal(());
|
||||
#[cfg(feature = "limit-fps")]
|
||||
embassy_time::Timer::after(FRAME_DURATION_MIN).await;
|
||||
SIGNAL_UI_RENDER.wait().await;
|
||||
}
|
||||
|
||||
slint::platform::set_platform(Box::new(backend))
|
||||
.expect("backend already initialized");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue