Skip to content

Commit 56fb211

Browse files
authored
Merge pull request #2 from Rahix/rahix-fixes
Fix incompatibility with avr-binutils >= 2.30
2 parents ceb702d + 2f84f0a commit 56fb211

File tree

4 files changed

+81
-14
lines changed

4 files changed

+81
-14
lines changed

.cargo/config.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[build]
2+
target = "avr-atmega328p.json"
3+
4+
[target.'cfg(target_arch = "avr")']
5+
runner = "./uno-runner.sh"
6+
7+
[unstable]
8+
build-std = ["core"]

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use avr_progmem::read_byte;
6666
// This `static` must never be directly dereferenced/accessed!
6767
// So a `let data: u8 = P_BYTE;` is **undefined behavior**!!!
6868
/// Static byte stored in progmem!
69-
#[link_section = ".progmem"]
69+
#[link_section = ".progmem.data"]
7070
static P_BYTE: u8 = b'A';
7171

7272
// Load the byte from progmem
@@ -92,7 +92,7 @@ Yet to make that also easier, this crate provides the [`progmem!`] macro
9292
(it has to be a macro), which will create a static variable in program
9393
memory for you and wrap it in the `ProgMem` struct. It will ensure that the
9494
`static` will be stored in the program memory by defining the
95-
`#[link_section = ".progmem"]` attribute on it. This makes the load
95+
`#[link_section = ".progmem.data"]` attribute on it. This makes the load
9696
functions on that struct sound and additionally prevents users to
9797
accidentally access that `static` directly, which, since it is in progmem,
9898
would be fundamentally unsound.
@@ -104,7 +104,7 @@ use avr_progmem::progmem;
104104

105105
// It will be wrapped in the ProgMem struct and expand to:
106106
// ```
107-
// #[link_section = ".progmem"]
107+
// #[link_section = ".progmem.data"]
108108
// static P_BYTE: ProgMem<u8> = unsafe { ProgMem::new(b'A') };
109109
// ```
110110
// Thus it is impossible for safe Rust to directly dereference/access it!

src/lib.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
//! // This `static` must never be directly dereferenced/accessed!
7979
//! // So a `let data: u8 = P_BYTE;` is **undefined behavior**!!!
8080
//! /// Static byte stored in progmem!
81-
//! #[link_section = ".progmem"]
81+
//! #[link_section = ".progmem.data"]
8282
//! static P_BYTE: u8 = b'A';
8383
//!
8484
//! // Load the byte from progmem
@@ -104,7 +104,7 @@
104104
//! (it has to be a macro), which will create a static variable in program
105105
//! memory for you and wrap it in the `ProgMem` struct. It will ensure that the
106106
//! `static` will be stored in the program memory by defining the
107-
//! `#[link_section = ".progmem"]` attribute on it. This makes the load
107+
//! `#[link_section = ".progmem.data"]` attribute on it. This makes the load
108108
//! functions on that struct sound and additionally prevents users to
109109
//! accidentally access that `static` directly, which, since it is in progmem,
110110
//! would be fundamentally unsound.
@@ -116,7 +116,7 @@
116116
//!
117117
//! // It will be wrapped in the ProgMem struct and expand to:
118118
//! // ```
119-
//! // #[link_section = ".progmem"]
119+
//! // #[link_section = ".progmem.data"]
120120
//! // static P_BYTE: ProgMem<u8> = unsafe { ProgMem::new(b'A') };
121121
//! // ```
122122
//! // Thus it is impossible for safe Rust to directly dereference/access it!
@@ -199,7 +199,7 @@ use cfg_if::cfg_if;
199199
/// 'best-effort' notation).
200200
///
201201
/// However, there is a rather simple way to make is sound, and that is defining
202-
/// the `#[link_section = ".progmem"]` (or `".text"`) on a static that contains
202+
/// the `#[link_section = ".progmem.data"]` (or `".text"`) on a static that contains
203203
/// this struct. And since its that simple, a macro `progmem!` is provided that
204204
/// will ensure this and should be always used to obtain a `ProgMem` instance
205205
/// in the first place.
@@ -252,7 +252,7 @@ impl<T> ProgMem<T> {
252252
///
253253
/// That means that this function is only sound to call, if the value is
254254
/// stored in a static that is for instance attributed with
255-
/// `#[link_section = ".progmem"]`.
255+
/// `#[link_section = ".progmem.data"]`.
256256
///
257257
/// However, the above requirement only applies to the AVR architecture
258258
/// (`#[cfg(target_arch = "avr")]`), because otherwise normal data access
@@ -401,7 +401,7 @@ macro_rules! progmem_internal {
401401
} => {
402402
// ProgMem must be stored in the progmem or text section!
403403
// The link_section lets us define it.
404-
#[cfg_attr(target_arch = "avr", link_section = ".progmem")]
404+
#[cfg_attr(target_arch = "avr", link_section = ".progmem.data")]
405405
// User attributes
406406
$(#[$attr])*
407407
// The actual static definition
@@ -493,7 +493,7 @@ macro_rules! progmem {
493493
/// // This static must never be directly dereferenced/accessed!
494494
/// // So a `let data: u8 = P_BYTE;` is Undefined Behavior!!!
495495
/// /// Static byte stored in progmem!
496-
/// #[link_section = ".progmem"]
496+
/// #[link_section = ".progmem.data"]
497497
/// static P_BYTE: u8 = b'A';
498498
///
499499
/// // Load the byte from progmem
@@ -512,7 +512,7 @@ macro_rules! progmem {
512512
/// Typically only function pointers (which make no sense here) and pointer to
513513
/// or into statics that are defined to be stored into progmem are valid.
514514
/// For instance, a valid progmem statics would be one, that is attributed with
515-
/// `#[link_section = ".progmem"]`.
515+
/// `#[link_section = ".progmem.data"]`.
516516
///
517517
/// Also general Rust pointer dereferencing constraints apply, i.e. it must not
518518
/// be dangling.
@@ -584,6 +584,7 @@ pub unsafe fn read_byte(p_addr: *const u8) -> u8 {
584584
/// However alignment is not strictly required for AVR, since the read/write is
585585
/// done byte-wise.
586586
///
587+
#[allow(dead_code)]
587588
unsafe fn read_byte_loop_raw<T>(p_addr: *const T, out: *mut T, len: u8)
588589
where T: Sized + Copy {
589590

@@ -778,7 +779,7 @@ unsafe fn read_value_raw<T>(p_addr: *const T, out: *mut T, len: u8)
778779
/// // Also notice the `*` in front of the string, because we want to store the
779780
/// // data, not just a reference!
780781
/// /// Static bytes stored in progmem!
781-
/// #[link_section = ".progmem"]
782+
/// #[link_section = ".progmem.data"]
782783
/// static P_ARRAY: [u8;11] = *b"Hello World";
783784
///
784785
/// // Notice since we use a sub-slice the data better is pre-initialized even
@@ -864,7 +865,7 @@ pub unsafe fn read_slice(p: &[u8], out: &mut [u8]) {
864865
/// // Also notice the `*` in front of the string, because we want to store the
865866
/// // data, not just a reference!
866867
/// /// Static bytes stored in progmem!
867-
/// #[link_section = ".progmem"]
868+
/// #[link_section = ".progmem.data"]
868869
/// static P_ARRAY: [u8;11] = *b"Hello World";
869870
///
870871
/// // Load the bytes from progmem
@@ -881,7 +882,7 @@ pub unsafe fn read_slice(p: &[u8], out: &mut [u8]) {
881882
/// use avr_progmem::read_value;
882883
///
883884
/// /// Static bytes stored in progmem!
884-
/// #[link_section = ".progmem"]
885+
/// #[link_section = ".progmem.data"]
885886
/// static P_ARRAY: [u8;11] = *b"Hello World";
886887
///
887888
/// // Get a sub-array reference without dereferencing it

uno-runner.sh

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env sh
2+
set -e
3+
4+
case "$(uname -s)" in
5+
Linux*) OS="Linux";;
6+
Darwin*) OS="Mac";;
7+
*) OS="Unknown";;
8+
esac
9+
10+
if ! command -v numfmt &> /dev/null
11+
then
12+
echo "numfmt is needed for human-readable sizes." >&2
13+
echo "please install https://command-not-found.com/numfmt" >&2
14+
alias numfmt=true
15+
fi
16+
17+
if ! command -v avrdude &> /dev/null
18+
then
19+
echo "required avrdude could not be found!" >&2
20+
echo "please install https://command-not-found.com/avrdude" >&2
21+
exit 1
22+
fi
23+
24+
if [ $OS = "Linux" ]; then
25+
SERIAL_PORT="/dev/ttyACM0"
26+
elif [ $OS = "Mac" ]; then
27+
SERIAL_PORT="/dev/cu.usbmodem146201"
28+
else
29+
echo "unsupported OS, things might not work" >&2
30+
SERIAL_PORT="/dev/ttyACM0"
31+
fi
32+
33+
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
34+
echo "usage: $0 <application.elf>" >&2
35+
exit 1
36+
fi
37+
38+
if [ "$#" -lt 1 ]; then
39+
echo "$0: no ELF file given" >&2
40+
exit 1
41+
fi
42+
43+
NAME="$(basename "$1")"
44+
SIZE_TEXT="$(avr-size "$1" | tail -1 | cut -f1)"
45+
SIZE_DATA="$(avr-size "$1" | tail -1 | cut -f2)"
46+
SIZE_BSS="$(avr-size "$1" | tail -1 | cut -f3)"
47+
48+
printf "\n"
49+
printf "Program: %s\n" "$NAME"
50+
printf "Size:\n"
51+
printf " .text %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_TEXT")" "$SIZE_TEXT"
52+
printf " .data %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_DATA")" "$SIZE_DATA"
53+
printf " .bss %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_BSS")" "$SIZE_BSS"
54+
printf "\n"
55+
printf "Attempting to flash ...\n"
56+
printf "\n"
57+
58+
avrdude -q -patmega328p -carduino -P"${SERIAL_PORT}" -D "-Uflash:w:$1:e"

0 commit comments

Comments
 (0)