Initial commit

This commit is contained in:
Travis Burtrum 2024-02-08 21:08:36 -05:00
commit ec1a638e20
22 changed files with 1186 additions and 0 deletions

View File

@ -0,0 +1,26 @@
cmake_minimum_required(VERSION 3.12)
# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)
project(pico_examples C CXX ASM)
set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 17)
# Initialize the SDK
pico_sdk_init()
add_executable(
blink
blink.c
)
# pull in common dependencies
target_link_libraries(
blink
pico_stdlib
/tmp/cargo-target/thumbv6m-none-eabi/release/librblink.a
)
# create map/bin/hex file etc.
pico_add_extra_outputs(blink)

61
c-with-rust/blink.c Normal file
View File

@ -0,0 +1,61 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "pico/stdlib.h"
// https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html
// bool is compatible
#define i8 int8_t
#define i16 int16_t
#define i32 int32_t
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define i64 int64_t
#define u64 uint64_t
#define isize intptr_t
#define usize uintptr_t
// used from rust
const uint LED_PIN = PICO_DEFAULT_LED_PIN;
uint led_pin() {
return PICO_DEFAULT_LED_PIN;
}
// without this: undefined reference to `gpio_set_dir'
void c_gpio_set_dir(uint gpio, bool out) {
return gpio_set_dir(gpio, out);
}
// without this: undefined reference to `gpio_put'
void c_gpio_put(uint gpio, bool value) {
return gpio_put(gpio, value);
}
// defined in rust
u32 add_half(u32 num);
int rs_main();
int c_main() {
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
int sleep = 250;
while (true) {
gpio_put(LED_PIN, 1);
sleep_ms(sleep);
gpio_put(LED_PIN, 0);
sleep_ms(sleep);
sleep = add_half(sleep);
}
}
// rename to main() to enable this one
int main_disabled() {
return rs_main();
//return c_main();
}

21
c-with-rust/build.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
set -euxo pipefail
# run: rustup target add thumbv6m-none-eabi
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd "$SCRIPT_DIR"/rblink
CARGO_TARGET_DIR=/tmp/cargo-target cargo build --release --target thumbv6m-none-eabi
mkdir -p /tmp/8
cd /tmp/8
cmake "$SCRIPT_DIR"
make
picotool info
picotool load blink.uf2
picotool reboot

View File

@ -0,0 +1,62 @@
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
endif ()
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
endif ()
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
include(${PICO_SDK_INIT_CMAKE_FILE})

7
c-with-rust/rblink/Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "rblink"
version = "0.1.0"

View File

@ -0,0 +1,10 @@
[package]
name = "rblink"
version = "0.1.0"
edition = "2021"
[lib]
name = "rblink"
crate-type = ["staticlib"]
[dependencies]

View File

@ -0,0 +1,73 @@
#![no_std]
// https://doc.rust-lang.org/core/ffi/index.html
use core::ffi::{c_int, c_uint, c_void};
#[panic_handler]
fn oh_no(_panic_info: &core::panic::PanicInfo) -> ! {
loop {}
}
mod c {
use core::ffi::{c_int, c_uint, c_void};
extern "C" {
pub(super) static LED_PIN: c_uint;
// https://www.raspberrypi.com/documentation/pico-sdk/high_level.html
pub(super) fn gpio_init(gpio: c_uint) -> c_void;
pub(super) fn c_gpio_set_dir(gpio: c_uint, on_off: bool) -> c_void;
pub(super) fn c_gpio_put(gpio: c_uint, on_off: bool) -> c_void;
pub(super) fn sleep_us(us: u64) -> c_void;
pub(super) fn sleep_ms(ms: u32) -> c_void;
}
}
static LED_PIN: &c_uint = unsafe { &c::LED_PIN };
fn gpio_init(gpio: c_uint) {
unsafe { c::gpio_init(gpio) };
}
fn gpio_set_dir(gpio: c_uint, on_off: bool) {
unsafe { c::c_gpio_set_dir(gpio, on_off) };
}
fn gpio_put(gpio: c_uint, on_off: bool) {
unsafe { c::c_gpio_put(gpio, on_off) };
}
fn sleep_us(us: u64) {
unsafe { c::sleep_us(us) };
}
fn sleep_ms(ms: u32) {
unsafe { c::sleep_ms(ms) };
}
// this is now the entry point
#[no_mangle]
pub extern "C" fn main() -> c_int {
rs_main()
}
#[no_mangle]
pub extern "C" fn rs_main() -> c_int {
let led_pin = *LED_PIN;
gpio_init(led_pin);
gpio_set_dir(led_pin, true);
let mut sleep = 250;
loop {
gpio_put(led_pin, true);
sleep_ms(sleep);
gpio_put(led_pin, false);
sleep_ms(sleep);
sleep = add_half(sleep);
}
}
#[no_mangle]
pub extern "C" fn add_half(num: u32) -> u32 {
let mut half = num / 2;
if half == 0 {
half = 1;
}
num.wrapping_add(half)
}

25
c/CMakeLists.txt Normal file
View File

@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.12)
# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)
project(pico_examples C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
# Initialize the SDK
pico_sdk_init()
add_executable(
blink
blink.c
)
# pull in common dependencies
target_link_libraries(
blink
pico_stdlib
)
# create map/bin/hex file etc.
pico_add_extra_outputs(blink)

19
c/blink.c Normal file
View File

@ -0,0 +1,19 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "pico/stdlib.h"
int main() {
const uint LED_PIN = PICO_DEFAULT_LED_PIN;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (true) {
gpio_put(LED_PIN, 1);
sleep_ms(250);
gpio_put(LED_PIN, 0);
sleep_ms(250);
}
}

16
c/build.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
set -euxo pipefail
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
mkdir -p /tmp/8
cd /tmp/8
cmake "$SCRIPT_DIR"
make
picotool info
picotool load blink.uf2
picotool reboot

62
c/pico_sdk_import.cmake Normal file
View File

@ -0,0 +1,62 @@
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
endif ()
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
endif ()
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
include(${PICO_SDK_INIT_CMAKE_FILE})

11
readme.txt Normal file
View File

@ -0,0 +1,11 @@
examples of blinking projects on rpi pico
one with C only
one with C using a static rust lib
one with rust using a static C lib
run ./build.sh in each of the directories to flash and run them to your rpi pico
If you have suggestions for better ways let me know

View File

@ -0,0 +1,29 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# Choose a default "cargo run" tool (see README for more info)
# - `probe-rs` provides flashing and defmt via a hardware debugger, and stack unwind on panic
# - elf2uf2-rs loads firmware over USB when the rp2040 is in boot mode
#runner = "probe-rs run --chip RP2040 --protocol swd"
#runner = "elf2uf2-rs -d"
# runner = "sh -c \"cp /tmp/cargo-target/thumbv6m-none-eabi/debug/rp2040-project-template /tmp/rp.elf && picotool load /tmp/rp.elf\""
# runner = "cp /tmp/cargo-target/thumbv6m-none-eabi/debug/rp2040-project-template /tmp/rp.elf && picotool load /tmp/rp.elf"
runner = "pico-load-elf.sh"
rustflags = [
"-C", "linker=flip-link",
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",
# Code-size optimizations.
# trap unreachable can save a lot of space, but requires nightly compiler.
# uncomment the next line if you wish to enable it
# "-Z", "trap-unreachable=no",
"-C", "inline-threshold=5",
"-C", "no-vectorize-loops",
]
[build]
target = "thumbv6m-none-eabi"
[env]
DEFMT_LOG = "debug"

380
rust-with-c/Cargo.lock generated Normal file
View File

@ -0,0 +1,380 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "arrayvec"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
[[package]]
name = "bare-metal"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
dependencies = [
"rustc_version",
]
[[package]]
name = "bitfield"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
[[package]]
name = "cc"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
[[package]]
name = "cmake"
version = "0.1.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
dependencies = [
"cc",
]
[[package]]
name = "cortex-m"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
dependencies = [
"bare-metal",
"bitfield",
"embedded-hal",
"volatile-register",
]
[[package]]
name = "cortex-m-rt"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1"
dependencies = [
"cortex-m-rt-macros",
]
[[package]]
name = "cortex-m-rt-macros"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "crc-any"
version = "2.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c01a5e1f881f6fb6099a7bdf949e946719fd4f1fefa56264890574febf0eb6d0"
dependencies = [
"debug-helper",
]
[[package]]
name = "critical-section"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
[[package]]
name = "debug-helper"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e"
[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "embedded-dma"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446"
dependencies = [
"stable_deref_trait",
]
[[package]]
name = "embedded-hal"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
dependencies = [
"nb 0.1.3",
"void",
]
[[package]]
name = "fugit"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7"
dependencies = [
"gcd",
]
[[package]]
name = "gcd"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "libc"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "nb"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
dependencies = [
"nb 1.1.0",
]
[[package]]
name = "nb"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
[[package]]
name = "num_enum"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
dependencies = [
"num_enum_derive",
]
[[package]]
name = "num_enum_derive"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "paste"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "pio"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76e09694b50f89f302ed531c1f2a7569f0be5867aee4ab4f8f729bbeec0078e3"
dependencies = [
"arrayvec",
"num_enum",
"paste",
]
[[package]]
name = "proc-macro2"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "rblink"
version = "0.1.0"
dependencies = [
"cmake",
"cortex-m",
"cortex-m-rt",
"embedded-hal",
"rp-pico",
]
[[package]]
name = "rp-pico"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aab28f6f4e19cec2d61b64cdd685e69794b81c579fd3b765579c46018fe616d0"
dependencies = [
"cortex-m",
"cortex-m-rt",
"fugit",
"rp2040-boot2",
"rp2040-hal",
"usb-device",
]
[[package]]
name = "rp2040-boot2"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c773ec49b836077aa144b58dc7654a243e1eecdb6cf0d25361ae7c7600fabd8"
dependencies = [
"crc-any",
]
[[package]]
name = "rp2040-hal"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1369bb84862d7f69391a96606b2f29a00bfce7f29a749e23d5f01fc3f607ada0"
dependencies = [
"cortex-m",
"critical-section",
"embedded-dma",
"embedded-hal",
"fugit",
"itertools",
"nb 1.1.0",
"paste",
"pio",
"rand_core",
"rp2040-hal-macros",
"rp2040-pac",
"usb-device",
"vcell",
"void",
]
[[package]]
name = "rp2040-hal-macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86479063e497efe1ae81995ef9071f54fd1c7427e04d6c5b84cde545ff672a5e"
dependencies = [
"cortex-m-rt",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "rp2040-pac"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9192cafbb40d717c9e0ddf767aaf9c69fee1b4e48d22ed853b57b11f6d9f3d7e"
dependencies = [
"cortex-m",
"cortex-m-rt",
"vcell",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "usb-device"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f6cc3adc849b5292b4075fc0d5fdcf2f24866e88e336dd27a8943090a520508"
[[package]]
name = "vcell"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "volatile-register"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc"
dependencies = [
"vcell",
]

69
rust-with-c/Cargo.toml Normal file
View File

@ -0,0 +1,69 @@
[package]
name = "rblink"
version = "0.1.0"
edition = "2021"
build="build.rs"
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
rp-pico = "0.7.0"
embedded-hal = { version = "0.2.5", features = ["unproven"] }
[build-dependencies]
cmake = "0.1"
# cargo build/run
[profile.dev]
codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
opt-level = 3
overflow-checks = true
# cargo build/run --release
[profile.release]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 3
overflow-checks = false
# do not optimize proc-macro crates = faster builds from scratch
[profile.dev.build-override]
codegen-units = 8
debug = false
debug-assertions = false
opt-level = 0
overflow-checks = false
[profile.release.build-override]
codegen-units = 8
debug = false
debug-assertions = false
opt-level = 0
overflow-checks = false
# cargo test
[profile.test]
codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
opt-level = 3
overflow-checks = true
# cargo test --release
[profile.bench]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 3

23
rust-with-c/build.rs Normal file
View File

@ -0,0 +1,23 @@
extern crate cmake;
use cmake::Config;
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
fn main() {
let dst = Config::new("libblink").build();
// Put `memory.x` in our output directory and ensure it's
// on the linker search path.
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
File::create(out.join("memory.x"))
.unwrap()
.write_all(include_bytes!("memory.x"))
.unwrap();
println!("cargo:rustc-link-search={}", out.display());
println!("cargo:rustc-link-search=native={}", dst.display());
println!("cargo:rustc-link-lib=static=blink");
}

13
rust-with-c/build.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/bash
set -euxo pipefail
# run: rustup target add thumbv6m-none-eabi
# run: cargo install flip-link
CARGO_TARGET_DIR=/tmp/cargo-target cargo build -vv --release --target thumbv6m-none-eabi
picotool info
mv /tmp/cargo-target/thumbv6m-none-eabi/release/rblink /tmp/rp.elf
picotool load /tmp/rp.elf
picotool reboot

View File

@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.12)
# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)
project(pico_examples C CXX ASM)
set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 17)
# Initialize the SDK
pico_sdk_init()
add_library(blink STATIC blink.c)
target_link_libraries(
blink
pico_stdlib
)
install(TARGETS blink DESTINATION .)

View File

@ -0,0 +1,56 @@
#include "pico/stdlib.h"
#include "pico/bootrom.h"
// https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html
// bool is compatible
#define i8 int8_t
#define i16 int16_t
#define i32 int32_t
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define i64 int64_t
#define u64 uint64_t
#define isize intptr_t
#define usize uintptr_t
// used from rust
const uint LED_PIN = PICO_DEFAULT_LED_PIN;
uint led_pin() {
return PICO_DEFAULT_LED_PIN;
}
// without this: undefined reference to `gpio_set_dir'
void c_gpio_set_dir(uint gpio, bool out) {
return gpio_set_dir(gpio, out);
}
// without this: undefined reference to `gpio_put'
void c_gpio_put(uint gpio, bool value) {
return gpio_put(gpio, value);
}
// defined in rust
u32 add_half(u32 num);
int rs_main();
int c_main() {
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
int sleep = 250;
while (true) {
gpio_put(LED_PIN, 1);
sleep_ms(sleep);
gpio_put(LED_PIN, 0);
sleep_ms(sleep);
sleep = add_half(sleep);
// in rust:
//reset_to_usb_boot(LED_PIN, 0);
if(sleep > 2000) {
reset_usb_boot(LED_PIN, 0);
}
}
}

View File

@ -0,0 +1,62 @@
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
endif ()
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
endif ()
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
include(${PICO_SDK_INIT_CMAKE_FILE})

15
rust-with-c/memory.x Normal file
View File

@ -0,0 +1,15 @@
MEMORY {
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
RAM : ORIGIN = 0x20000000, LENGTH = 256K
}
EXTERN(BOOT2_FIRMWARE)
SECTIONS {
/* ### Boot loader */
.boot2 ORIGIN(BOOT2) :
{
KEEP(*(.boot2));
} > BOOT2
} INSERT BEFORE .text;

125
rust-with-c/src/main.rs Normal file
View File

@ -0,0 +1,125 @@
#![no_std]
#![no_main]
use bsp::entry;
// Provide an alias for our BSP so we can switch targets quickly.
// Uncomment the BSP you included in Cargo.toml, the rest of the code does not need to change.
use rp_pico as bsp;
// use sparkfun_pro_micro_rp2040 as bsp;
use bsp::hal::{
clocks::{init_clocks_and_plls, Clock},
pac,
sio::Sio,
watchdog::Watchdog,
};
// https://doc.rust-lang.org/core/ffi/index.html
use core::ffi::{c_int, c_uint, c_void};
#[panic_handler]
fn oh_no(_panic_info: &core::panic::PanicInfo) -> ! {
loop {}
}
mod c {
use core::ffi::{c_int, c_uint, c_void};
#[link(name = "blink", kind = "static")]
extern "C" {
pub(super) static LED_PIN: c_uint;
// https://www.raspberrypi.com/documentation/pico-sdk/high_level.html
pub(super) fn gpio_init(gpio: c_uint) -> c_void;
pub(super) fn c_gpio_set_dir(gpio: c_uint, on_off: bool) -> c_void;
pub(super) fn c_gpio_put(gpio: c_uint, on_off: bool) -> c_void;
pub(super) fn sleep_us(us: u64) -> c_void;
pub(super) fn sleep_ms(ms: u32) -> c_void;
pub(super) fn c_main() -> c_void;
}
}
static LED_PIN: &c_uint = unsafe { &c::LED_PIN };
fn gpio_init(gpio: c_uint) {
unsafe { c::gpio_init(gpio) };
}
fn gpio_set_dir(gpio: c_uint, on_off: bool) {
unsafe { c::c_gpio_set_dir(gpio, on_off) };
}
fn gpio_put(gpio: c_uint, on_off: bool) {
unsafe { c::c_gpio_put(gpio, on_off) };
}
fn sleep_us(us: u64) {
unsafe { c::sleep_us(us) };
}
fn sleep_ms(ms: u32) {
unsafe { c::sleep_ms(ms) };
}
#[no_mangle]
pub extern "C" fn rs_main() -> c_int {
let led_pin = *LED_PIN;
gpio_init(led_pin);
gpio_set_dir(led_pin, true);
let mut sleep = 250;
loop {
gpio_put(led_pin, true);
sleep_ms(sleep);
gpio_put(led_pin, false);
sleep_ms(sleep);
sleep = add_half(sleep);
}
}
#[no_mangle]
pub extern "C" fn add_half(num: u32) -> u32 {
let mut half = num / 2;
if half == 0 {
half = 1;
}
num.wrapping_add(half)
}
#[entry]
fn main() -> ! {
let mut pac = pac::Peripherals::take().unwrap();
let mut watchdog = Watchdog::new(pac.WATCHDOG);
let sio = Sio::new(pac.SIO);
// External high-speed crystal on the pico board is 12Mhz
let external_xtal_freq_hz = 12_000_000u32;
let clocks = init_clocks_and_plls(
external_xtal_freq_hz,
pac.XOSC,
pac.CLOCKS,
pac.PLL_SYS,
pac.PLL_USB,
&mut pac.RESETS,
&mut watchdog,
)
.ok()
.unwrap();
let pins = bsp::Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);
//use embedded_hal::watchdog::WatchdogEnable;
//watchdog.start(10);
//rs_main();
unsafe { c::c_main() };
loop{}
}