How to Flash Baochip on Baosec
At a high level, you compile the xous code wherever you're programming and copy it over to a raspberrypi using one script. Then run a different script program the chip over a raspberry pi. In order to view the console output you need to be connected to the duart which are labeled.
How everything should be connected
Okay - at a high level you have 4 boards to consider 1. raspberry pi, 2. the raspberry pi hat and 3. the device (baosec), 4. baosec breakout board.
Images of how the cables and debug uart are connected
## Initial state showing raspberry pi, raspberry pi hat and the baosec.The raspberry pi hat goes on to the raspberry pi.
Debug UART is attached where TX and GND are labeled (no RX). Note also how the cable is bent.
An image of the UART connected
Images of how the baosec and baosec breakout board are connected
Image of the FPC connector. Note how the contacts are face down and that it is aligned to pin one
Image of the cable seated in the FPC connector in the proper orientation
bio pinouts of the baosec breakout board
Images of the relevant parts of the baosec camera connector which we break out using the baosec breakout board.
Example of compile and copy script
An example of the bash script which compiles and then copies the code to a raspberry pi.
#!/bin/bash
set -e
USE_EVB=0
for arg in "$@"; do
if [[ "$arg" == "--evb" ]]; then
USE_EVB=1
break
fi
done
HOST=bunnie@10.0.245.50:code/jtag-tools # sam
if [[ $USE_EVB -eq 1 ]]; then
cargo xtask baremetal-cramsoc-evb --loader-feature v0p9 --loader-feature nto-bio
scp target/riscv32imac-unknown-none-elf/release/baremetal $EVBHOST
else
cargo xtask baremetal-cramsoc --loader-feature v0p9 --loader-feature nto-bio
scp target/riscv32imac-unknown-none-elf/release/baremetal.img $HOST/baremetal.bin
fi
md5sum target/riscv32imac-unknown-none-elf/release/baremetal.imgThe flashing script
Note this must be run in jtag-tools on the raspberry pi. Also note that this is not the main branch!
The baremetal nto flasher script
``` md5sum baremetal.bin sudo python ./rram_burn_2101.py -f baremetal.bin --exec --xous-region loader --no-verify ```How to compile code
- On one
sshwindow runsudo screen /dev/ttyS0 115200- this is where you will type. You should seeconsole up - On a second
sshwindow runscreen /dev/ttyUSB0 1000000- this is where you will see the output - On a third
sshwindow run~/code/jtag-tools
On your personal machine, compile some code using the compile and copy script: ./loadbao.sh. This will put a copy onto your pi if you have the proper HOST.
Now you can run some commands:
- to upload
sudo ./baremetal.sh - to turn off the bus:
sudo ./vbus.sh 0 - to turn on the bus:
sudo ./vbus.sh 1 - to reset:
sudo ./reset.sh
Activity
3Neat Links:
some tests: https://github.com/betrusted-io/xous-core/blob/main/libs/xous-bio/src/bio_tests/units.rs a minimal overview of how the registers work: https://github.com/betrusted-io/xous-core/blob/main/libs/xous-bio/src/lib.rs overview of the UTRA: https://github.com/betrusted-io/xous-core/tree/main/svd2utra#readme https://github.com/betrusted-io/xous-core/blob/nto-bringup/baremetal/src/repl.rs
./code/jtag-tools-new
bunnie@raspberrypi:~ $ screen /dev/ttyS0 1000000
[screen is terminating]
bunnie@raspberrypi:~ $
bunnie@raspberrypi:~ $ cd code/jtag-tools-
jtag-tools-bak/ jtag-tools-mpw/ jtag-tools-new/ jtag-tools-RISCV/
bunnie@raspberrypi:~ $ cd code/jtag-tools-new/
bunnie@raspberrypi:/code/jtag-tools-new $ python3 ./uf2send.py baremetal.uf2
[ERROR] Serial port: Failed to open serial port /dev/ttyACM0: [Errno 2] could not open port /dev/ttyACM0: [Errno 2] No such file or directory: '/dev/ttyACM0'
Try listing available ports with: ./uf2send.py --list-ports
bunnie@raspberrypi:/code/jtag-tools-new $ ls /dev/tty
tty tty11 tty15 tty19 tty22 tty26 tty3 tty33 tty37 tty40 tty44 tty48 tty51 tty55 tty59 tty62 tty9 ttyUSB0
tty0 tty12 tty16 tty2 tty23 tty27 tty30 tty34 tty38 tty41 tty45 tty49 tty52 tty56 tty6 tty63 ttyAMA0
tty1 tty13 tty17 tty20 tty24 tty28 tty31 tty35 tty39 tty42 tty46 tty5 tty53 tty57 tty60 tty7 ttyprintk
tty10 tty14 tty18 tty21 tty25 tty29 tty32 tty36 tty4 tty43 tty47 tty50 tty54 tty58 tty61 tty8 ttyS0
bunnie@raspberrypi:/code/jtag-tools-new $ ls /dev/tty^C
bunnie@raspberrypi:/code/jtag-tools-new $ python3 ./uf2send.py baremetal.uf2 -p /dev/ttyS0
============================================================ UF2 Transfer Starting
File: baremetal.uf2 Port: /dev/ttyS0 @ 1000000 baud Total blocks: 546 Retry limit: 3 attempts per block Failure threshold: 5 blocks
Transfer: 100% [███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████] Time: 0:00:09 | OK (Retries: 0)
============================================================ Transfer Summary
Total blocks: 546 Successful: 546 (100.0%) Failed: 0 Total retries: 0
bio
Reading the
SFR_CTRLregister.https://ci.betrusted.io/cramium/bio_bdma.html#bio-bdma-sfr-ctrl
https://github.com/betrusted-io/xous-core/blob/main/svd2utra/README.md
The library provides the a function template for
CSRthat provides the following methods:.r(reg: Register) -> T- Read. Reads the entire contents of a CSR.rf(field: Field) -> T- Read Field. Read a CSR and return only the masked and shifted value of a sub-field.wo(reg: Register, value:T)- Write only. Writevalueinto a register, replacing its entire contents.wfo(field: Field, value:T)- Write field only. Writevalueinto a field of a register, zeroizing all the other fields and replacing its entire contents.rmwf(field: Field, value:T)- Read-modify-write a register. Replace just the contents offieldwhile leaving the other fields intact. The current implementation makes no guarantees about atomicity.Users that require multiple bit fields to be set simultaneously must explicitly read the CSR value, bind it to a temporary variable, mask out the fields they want to replace, and combine in the values before writing it back to the CSR.
To aid with this, the following helper functions are also available:
zf(field:Field, value:T) -> T- Zeroize field. Take bits corresponding tofieldand set it to zero invalue, leaving other bits unchangedms(field:Field, value:T) -> T- Mask and shift. Take value, mask it to the field width, and then shift to its final position.DocsGPT?
BIO Subsystem Register Guide
This document provides an overview of the key registers and concepts for programming the BIO (Bit I/O) subsystem. Understanding these components is crucial for controlling the four independent RISC-V cores and their shared GPIO peripheral.
BIO Cores
The BIO subsystem contains four independent RISC-V cores, referred to as Core 0, Core 1, Core 2, and Core 3.
x31.x31[31:30]: Core IDSFR_CTRL- The Core Control RegisterThe
SFR_CTRLregister is the primary mechanism for managing the state of the four BIO cores. It is a 12-bit register where specific bits control the enable and restart signals for each core.Bit Layout
EN[3:0]1in bitienables (runs) Corei. A0halts it.RESTART[7:4]1in biti+4resets the program counter for Corei.CLKDIV_RESTART[11:8]1in biti+8restarts the clock divider for Corei.Usage
To start a core cleanly, it's necessary to set its corresponding bits in all three fields (
EN,RESTART, andCLKDIV_RESTART). For example, to start Core 2, you would set bits 2, 6, and 10. The corresponding mask would be0x444.A common hardware quirk requires that the
RESTARTandCLKDIV_RESTARTbits for Core 0 are set during any start operation to ensure system-wide clock stability. Therefore, a robust start mask for atarget_coreis typically(mask_for_target_core | 0x111).GPIO Control:
x26andx21The most critical concept for multi-core GPIO control is the cooperative interaction between the
x26(mask) andx21(data) registers.x26- GPIO Mask RegisterThe
x26register is a shared, 32-bit read/write register that acts as a write-mask for actions on the GPIO pins. Any operation that modifies the GPIO pins is first filtered by this mask.x21- GPIO Data RegisterThe
x21register is a shared, 32-bit read/write register. Writing to it modifies the state of the GPIO output pins.The
(x26 & x21)InteractionThe hardware does not directly apply the value written to
x21to the pins. Instead, it performs a bitwise AND operation and uses the result. The rule is:output_to_pins = (value_in_x26 & value_written_to_x21)This mechanism is the key to safe multi-core operation. It allows a core to affect only the specific pin(s) it cares about without overwriting the state of other pins.
Example: Setting Pin 10 High
pin_maskfor pin 10:0x00000400.mv x26, pin_mask. The sharedx26register now holds0x00000400.mv x21, 0xFFFFFFFF.(0x00000400 & 0xFFFFFFFF) = 0x00000400.x26mask again to determine which pins to update. Since only bit 10 is set inx26, only pin 10 is affected. It is driven high, and the other 31 pins are left in their previous state.This prevents the race conditions and destructive writes associated with direct port manipulation, allowing all four cores to drive different GPIO pins concurrently.