在樹莓派 Pico 小小的板子上總是能讓我們發現一些驚喜。其所使用的RP2040芯片還具備8個可編程I/O(PIO)狀態機,用于自定義外圍設備,與 FPGA 類似,開發者可以靈活的使用 PIO 自定義功能。
可編程I/O(PIO)是為 RP2040 開發的一種新型硬件,可以通過 PIO 創建新類型的(或附加)硬件接口。通過使用 PIO ,可以模擬更多,更豐富,更快的硬件接口,有助于提升性能和擴展性。
與 PIO 相比,FPGA 往往更加昂貴,而且需要使用其他的編程模式編寫程序。但 PIO 僅僅只需要通過匯編語言就可以實現,開發者不需要去適應 FPGA 那種編程模式即可很快的實現自定義硬件接口。
PIO 一個簡單的 demo:
主要需要用到一個匯編實現的pio文件,一些C文件,和Cmake文件,實現串口打印 hello
pio文件:
.program hello
; Repeatedly get one word of data from the TX FIFO, stalling when the FIFO is
; empty. Write the least significant bit to the OUT pin group.
loop:
pull
out pins, 1
jmp loop
% c-sdk {
static inline void hello_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_sm_config c = hello_program_get_default_config(offset);
// Map the state machine's OUT pin group to one pin, namely the pin
// parameter to this function.
sm_config_set_out_pins(&c, pin, 1);
// Set this pin's GPIO function (connect PIO to the pad)
pio_gpio_init(pio, pin);
// Set the pin direction to output at the PIO
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
// Load our configuration, and jump to the start of the program
pio_sm_init(pio, sm, offset, &c);
// Set the state machine running
pio_sm_set_enabled(pio, sm, true);
}
%}
其流程主要如下:
將程序加載到PIO的指令存儲器中;
設置PIO狀態機以運行程序;
在狀態機運行時與狀態機交互。
C文件:
#include "pico/stdlib.h"
#include "hardware/pio.h"
// Our assembled program:
#include "hello.pio.h"
int main() {
#ifndef PICO_DEFAULT_LED_PIN
#warning pio/hello_pio example requires a board with a regular LED
#else
// Choose which PIO instance to use (there are two instances)
PIO pio = pio0;
// Our assembled program needs to be loaded into this PIO's instruction
// memory. This SDK function will find a location (offset) in the
// instruction memory where there is enough space for our program. We need
// to remember this location!
uint offset = pio_add_program(pio, &hello_program);
// Find a free state machine on our chosen PIO (erroring if there are
// none). Configure it to run our program, and start it, using the
// helper function we included in our .pio file.
uint sm = pio_claim_unused_sm(pio, true);
hello_program_init(pio, sm, offset, PICO_DEFAULT_LED_PIN);
// The state machine is now running. Any value we push to its TX FIFO will
// appear on the LED pin.
while (true) {
// Blink
pio_sm_put_blocking(pio, sm, 1);
sleep_ms(500);
// Blonk
pio_sm_put_blocking(pio, sm, 0);
sleep_ms(500);
}
#endif
}
我們會發現其中調用了 “hello.pio.h” 頭文件,其與之前的 pio 文件相關,但 pio 文件并不能在 c 文件中直接調用,于是就需要 Cmake 文件將 pio 文件和 c 文件聯系到一起,并構建一個可執行文件。
Cmake文件
add_executable(hello_pio)
pico_generate_pio_header(hello_pio ${CMAKE_CURRENT_LIST_DIR}/hello.pio)
target_sources(hello_pio PRIVATE hello.c)
target_link_libraries(hello_pio PRIVATE
pico_stdlib
hardware_pio
)
pico_add_extra_outputs(hello_pio)
add url via pico_set_program_url
example_auto_set_url(hello_pio)
其中的 pico_generate_pio_header 非常重要,其將之前用匯編語言寫的 pio 文件生成為一個 .h 頭文件,以供 c 文件調用。
通過這寫文件和 pico 官方提供的 sdk 就可以構建一個串口打印 hello 的程序了。
其他
我是在移植 pico-w 板載的 Wi-Fi 功能時注意到這一功能的,因為需要使用到 cyw43_bus_pio_spi.pio 。但是由于 RT-Thread 這邊使用的是 Scons,于是我就先利用 pico-examples 的 cmake 生成該 pio文件對應的 .h 文件 cyw43_bus_pio_spi.pio.h 然后復制過來是以供項目調用。
-
FPGA
+關注
關注
1626文章
21666瀏覽量
601837 -
存儲器
+關注
關注
38文章
7452瀏覽量
163605 -
狀態機
+關注
關注
2文章
492瀏覽量
27478 -
RT-Thread
+關注
關注
31文章
1272瀏覽量
39920 -
樹莓派
+關注
關注
116文章
1698瀏覽量
105524
發布評論請先 登錄
相關推薦
評論