Raspberry Pico点亮LED灯
点亮Pico的LED灯,是Raspberry官方的教程的第一示例,也是最容易的示例。但是官方教程,包括网上其他各类教程,都是使用官方推荐的Visual Studio Code最为默认开发工具。 即使是官方的examples,也只是介绍了如何编译和生成uf2文件,并没有讲如何单独编写blink和编译生成二进制文件。 这里介绍如何完全手动创建一个点亮led的项目,并编写cmake的编译文件,无需第三方工具自动生成。 如果有兴趣,可以研究examples目录下的CMakeLists.txt文件,可以学到如何配置但项目示例的CMakeLists。
一、项目准备工作
1. 工具
本示例未使用官方推荐的VSC,而仅仅使用vim编写代码,然后使用编写cmake文件和交叉编译工具链进行编译
- arm-gcc交叉编译工具;
- 编辑器:vim
2. 新建项目文件夹
- 这里新建一个blink目录,后面的C代码和cmake文件均在此目录下。
- 后面的编译操作也在此目录下进行(这里的编译与官方example示例编译不同,无需建立build目录和编译,更方便学习和编译小项目示例)
二、编写blink代码
blink代码很简单,原理就是给gpio一个信号是高低电平来点亮还是熄灭led灯,然后通过指定一段线程sleep时间。
1. 代码
#include "pico/stdlib.h"
int main() {
#ifndef PICO_DEFAULT_LED_PIN
#warning blink example requires a board with a regular LED
#else
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(1000);
gpio_put(LED_PIN, 0);
sleep_ms(1000);
}
#endif
}
2. 说明
- Pico开发板上自带一个led灯,默认的gpio编号为25,可以手动指定,也可以使用系统变量;
- 如果使用自己外插的发光二极管,需要手动指定gpio的编号;
三、配置项目环境
1. 编写pico_sdk_import.cmake
将官方示例的pico_sdk_import.cmake文件拷贝至blink目录下,如果没有从github上下载官方示例,可以使用下面代码 看代码的注释可知,此cmake的文件主要作用是设置pico sdk的路径
# 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})
2. 编写CMakeLists.txt
cmake文件,用于初始化sdk和指定编译的项目信息.
说明
- cmake_minimum_required:指定cmake程序最低版本,我的版本是3.16,实际中可以指定的稍微低一点;
- include:引入上面的pico_sdk_import.cmake,配置pico sdk路径;
- project:设置blink的项目名称,可以与项目名称一致,也可以不同;
- pico_sdk_init:初始化pico sdk;
- 最后面三行,用于配置blink的信息,如C代码名称、生成二进制文件的名称等
- cmake文件的编写, 要注意顺序(强调三遍)
cmake_minimum_required(VERSION 3.12)
include(pico_sdk_import.cmake)
project(pico-blink)
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)
四、编译代码
blink.c代码和项目cmake编译配置文件完成后,即可编译项目,生成uf2等二进制文件
1. cmake生成makefile
在当前目录(blink)下,运行
cmake .
命令,系统自动生成makefile
文件,如C代码和配置文件无误,会顺利生成成功,并在项目目录下生成一大堆文件,如下:
cmake . ✔ 10:44:20
Using PICO_SDK_PATH from environment ('/home/neal/rasp-pico/pico-sdk')
PICO_SDK_PATH is /home/neal/rasp-pico/pico-sdk
Defaulting PICO_PLATFORM to rp2040 since not specified.
Defaulting PICO platform compiler to pico_arm_gcc since not specified.
-- Defaulting build type to 'Release' since not specified.
PICO compiler is pico_arm_gcc
-- The C compiler identification is GNU 9.2.1
-- The CXX compiler identification is GNU 9.2.1
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/arm-none-eabi-gcc
Defaulting PICO target board to pico since not specified.
Using board configuration from /home/neal/rasp-pico/pico-sdk/src/boards/include/boards/pico.h
-- Found Python3: /usr/bin/python3.8 (found version "3.8.10") found components: Interpreter
TinyUSB available at /home/neal/rasp-pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; enabling build support for USB.
-- Configuring done
-- Generating done
-- Build files have been written to: /home/neal/rasp-pico/pico-learn/blink
2. make编译
makefile生成后,即可使用
make
进行项目的链接和编译,编译成功后,会在项目目录下生成blink.uf2等二进制文件,拷入pico开发板,即可运行。
make ✔ 10:44:25
Scanning dependencies of target ELF2UF2Build
[ 1%] Creating directories for 'ELF2UF2Build'
[ 3%] No download step for 'ELF2UF2Build'
[ 5%] No patch step for 'ELF2UF2Build'
[ 6%] No update step for 'ELF2UF2Build'
[ 8%] Performing configure step for 'ELF2UF2Build'
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
省略...
[ 96%] Building C object CMakeFiles/blink.dir/home/neal/rasp-pico/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj
[ 98%] Building C object CMakeFiles/blink.dir/home/neal/rasp-pico/pico-sdk/src/rp2_common/pico_stdio_uart/stdio_uart.c.obj
[100%] Linking CXX executable blink.elf
[100%] Built target blink
五、关于cmake和make
pico开发需要pico sdk的支持,这就相当于引入第三方C库,要用到cmake和make,与仅仅编译单文件的C代码不同。 以下关于cmake和make介绍,转自网络^_^
- gcc:它是GNU Compiler Collection(就是GNU编译器套件),也可以简单认为是编译器,它可以编译很多种编程语言(括C、C++、Objective-C、Fortran、Java等等)。我们的程序只有一个源文件时,直接就可以用gcc命令编译它
- make:make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用makefile文件中用户指定的命令来进行编译和链接的。
- makefile:make工具就根据makefile中的命令进行编译和链接的。makefile命令中就包含了调用gcc(也可以是别的编译器)去编译某个源文件的命令。
- cmake:cmake就可以更加简单的生成makefile文件给上面那个make用。根据一个叫CMakeLists.txt文件(学名:组态档)去生成makefile。
- CMakeLists.txt:cmake的配置文件。