Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Моё решение

Какое решение вы придумали?

Вот моё. Это, вероятно, один из самых простых (хотя, конечно, не самых красивых) способов получить нужную матрицу:

#![deny(unsafe_code)]
#![no_main]
#![no_std]

use cortex_m_rt::entry;
use microbit::{board::Board, display::blocking::Display, hal::Timer};
use panic_rtt_target as _;
use rtt_target::rtt_init_print;

#[rustfmt::skip]
const PIXELS: [(usize, usize); 16] = [
    (0, 0),
    (0, 1),
    (0, 2),
    (0, 3),
    (0, 4),
    (1, 4),
    (2, 4),
    (3, 4),
    (4, 4),
    (4, 3),
    (4, 2),
    (4, 1),
    (4, 0),
    (3, 0),
    (2, 0),
    (1, 0),
];

#[entry]
fn main() -> ! {
    rtt_init_print!();

    let board = Board::take().unwrap();
    let mut timer = Timer::new(board.TIMER0);
    let mut display = Display::new(board.display_pins);
    #[rustfmt::skip]
    let mut leds = [
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0],
    ];

    let mut last_led = (0, 0);

    loop {
        for current_led in PIXELS {
            leds[last_led.0][last_led.1] = 0;
            leds[current_led.0][current_led.1] = 1;
            display.show(&mut timer, leds, 200);
            last_led = current_led;
        }
    }
}

И ещё кое-что! Проверьте, что ваше решение работает и в сборке «release»:

$ cargo embed --release

Если хотите отлаживать бинарник «release», понадобится другая команда GDB:

$ gdb ../../../target/thumbv7em-none-eabihf/release/led-roulette

Компилятор Rust изменяет машинные инструкции, которые генерируются в release-сборке (иногда очень сильно), чтобы сделать код быстрее или меньше. К сожалению, после этого GDB с трудом разбирается в происходящем. Поэтому отлаживать release-сборки с GDB бывает непросто.

За размером бинарника всегда стоит следить! Насколько велико ваше решение? Проверить это можно командой size для release-бинарника:

$ cargo size --release -- -A
    Finished release [optimized + debuginfo] target(s) in 0.02s
led-roulette  :
section              size        addr
.vector_table         256         0x0
.text                6332       0x100
.rodata               648      0x19bc
.data                   0  0x20000000
.bss                 1076  0x20000000
.uninit                 0  0x20000434
.debug_loc           9036         0x0
.debug_abbrev        2754         0x0
.debug_info         96460         0x0
.debug_aranges       1120         0x0
.debug_ranges       11520         0x0
.debug_str          71325         0x0
.debug_pubnames     32316         0x0
.debug_pubtypes     29294         0x0
.Arm.attributes        58         0x0
.debug_frame         2108         0x0
.debug_line         19303         0x0
.comment              109         0x0
Total              283715

Ваши числа могут немного отличаться в зависимости от того, как собран код: это нормально.

Умеете читать этот вывод? Секция text содержит инструкции программы. Секция rodata содержит данные только для чтения, которые хранятся вместе с инструкциями программы. Секции data и bss содержат переменные, выделенные статически в RAM (static-переменные). Если вы помните характеристики micro:bit, то заметите, что его флеш-память меньше чем вдвое больше размера этого очень простого бинарника. Может ли это быть правдой? Как видно из статистики размеров, основную часть бинарника составляют отладочные секции. Однако они никогда не прошиваются в микроконтроллер: для выполнения программы они не нужны.