Raspberry Pico点亮LED灯

点亮Pico的LED灯,是Raspberry官方的教程的第一示例,也是最容易的示例。但是官方教程,包括网上其他各类教程,都是使用官方推荐的Visual Studio Code最为默认开发工具。 即使是官方的examples,也只是介绍了如何编译和生成uf2文件,并没有讲如何单独编写blink和编译生成二进制文件。 这里介绍如何完全手动创建一个点亮led的项目,并编写cmake的编译文件,无需第三方工具自动生成。 如果有兴趣,可以研究examples目录下的CMakeLists.txt文件,可以学到如何配置但项目示例的CMakeLists。

一、项目准备工作

1. 工具

本示例未使用官方推荐的VSC,而仅仅使用vim编写代码,然后使用编写cmake文件和交叉编译工具链进行编译

  1. arm-gcc交叉编译工具;
  2. 编辑器:vim

    2. 新建项目文件夹

    1. 这里新建一个blink目录,后面的C代码和cmake文件均在此目录下。
    2. 后面的编译操作也在此目录下进行(这里的编译与官方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和指定编译的项目信息.

说明

  1. cmake_minimum_required:指定cmake程序最低版本,我的版本是3.16,实际中可以指定的稍微低一点;
  2. include:引入上面的pico_sdk_import.cmake,配置pico sdk路径;
  3. project:设置blink的项目名称,可以与项目名称一致,也可以不同;
  4. pico_sdk_init:初始化pico sdk;
  5. 最后面三行,用于配置blink的信息,如C代码名称、生成二进制文件的名称等
  6. 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介绍,转自网络^_^

  1. gcc:它是GNU Compiler Collection(就是GNU编译器套件),也可以简单认为是编译器,它可以编译很多种编程语言(括C、C++、Objective-C、Fortran、Java等等)。我们的程序只有一个源文件时,直接就可以用gcc命令编译它
  2. make:make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用makefile文件中用户指定的命令来进行编译和链接的。
  3. makefile:make工具就根据makefile中的命令进行编译和链接的。makefile命令中就包含了调用gcc(也可以是别的编译器)去编译某个源文件的命令。
  4. cmake:cmake就可以更加简单的生成makefile文件给上面那个make用。根据一个叫CMakeLists.txt文件(学名:组态档)去生成makefile。
  5. CMakeLists.txt:cmake的配置文件。

results matching ""

    No results matching ""

    results matching ""

      No results matching ""