K210 Developer Kit 学习日记1【全文4W字】

区分新版和旧版的IMU

k210 开发板更换了 IMU 型号,新版和旧版的源码不兼容,
新版的陀螺仪型号为 icm-40607 , 而旧版的为 icm-20607

硬件丝印是1.1的用新固件;     印1.0或0.1的旧固件

新版测试固件需要下载k210testV2.7以上 的版本
旧版测试固件需要下载k210testV2.7 以下 的版本

主控芯片简介K210

K210芯片内部是双核CPU,指令集为RISC-V 64位,每个核心内置独立FPU,可以单独进行浮点运算;

K210芯片自带计算卷积人工神经网络加速器KPU,以及处理麦克风阵列的APU,能够进行高性能机器视觉和听觉处理;

K210还内置快速傅里叶变换加速器,可以进行复数FFT计算;

K210芯片很注重安全性内置AES和SHA256算法加速器,为用户的数据安全提供有效保障;

K210芯片具有丰富的外设单元,分别是DVP、JTAG、OTP、FPIOA、GPIO、UART、SPI、RTC、I2S、I2C、WDT、TIMER、PWM,这些外设在实际使用中发挥巨大的作用,基本满足大部分MCU外设的需求;

K210拥有高性能、低功耗的SRAM,总共8M,2M专用于AI计算,6M用于程序;专用外置FLASH接口,增加自身的储存空间;数据传输可使用功能强大的DMA,在数据吞吐能力方面性能优异;

以下是K210芯片架构图,仅供参考,具体参考信息可查阅K210芯片的技术手册文档:

RISC-V具有以下特点:

1.完全开源:任何企业都可以自由免费使用RISC-V指令集来制造并营销自己的芯片,而不需要支付高额授权费,并且可以根据自己的需求扩展指令集,自己扩展的指令集不必开放,可以实现差异化发展。

2.架构简单:与主流的X86和ARM架构相比,RISC-V是一个全新的指令集,不需要兼容老旧产品,所以显得格外简洁,整个RISC-V基础指令集只有40多条,加上其他的模块化扩展指令总共也就只有几十条。

3.易于移植,现代操作系统都做了特权级指令和用户级指令的分离,特权指令只能操作系统调用,而用户级指令才能在用户模式调用,保障操作系统的稳定。RISC-V提供了特权级指令和用户级指令,同时提供了详细的RISC-V特权级指令规范和RISC-V用户级指令规范的详细信息,使开发者能非常方便的移植linux和unix系统到RISC-V平台。

4.模块化设计:RISC-V架构可以由不同模块组成不同功能,灵活利用模块的组合情况,可以定制属于自己需求的MCU。例如针对小面积低功耗的嵌入式场景,可以选择RV32IC组合的指令集,仅使用机器模式,就可以大大降低功耗和自身体积;而高性能的应用操作系统场景可以选择RV32IMFDC指令集,可以使用机器模式和用户模式,从而实现更高性能。

5.完整的工具链:工具链对于CPU来说,就可以理解为螺丝刀对于螺丝,没有螺丝刀的作用,螺丝是根本无法固定住发挥自身的性能的。工具链是软件开发与CPU交互的窗口,如果没有工具链,软件开发者甚至无法让CPU工作起来。幸运的是,RISC-V由于贡献者多年的热心贡献,社区已经提供了完整的工具链,并且由RISC-V基金会维护该工具链

OV9655驱动异常解决

因为OV9655的通信时序比OV2640的通信时序慢一些,所以为了确保OV9655和K210能通信,一定要做以下步骤,否则OV9655将无法在K210使用。

第一步:打开一个完整的工程,找到dvp.c的源文件,一般在D:k210kendryte-standalone-sdk-developlibdrivers下,红色路径是工程的自定义路径,然后找到dvp_sccb_start_transfer这函数;或者用Visual Studio Code打开完整的工程,使用搜索功能,搜索dvp_sccb_start_transfer这函数,如图所示:

图片.png

第二步:给dvp_sccb_start_transfer这函数增加这句代码mdelay(5);如图所示

图片.png

2.1 安装CH340驱动

本次安装CH340驱动以win10x64系统为例如果已经安装CH340驱动的朋友可以忽略以下安装步骤

一、安装CH340串口驱动

1.解压CH340压缩包Uart drive(CH340).zip,并且双击打开CH341SER.EXE程序

image.png

2.点击安装。

image.png

3.安装完成后会提示安装成功。

image.png

4.用Type-C数据线将K210开发板和电脑进行连接,然后依次右击桌面的 ‘此电脑’->‘属性’->‘设备管理器’->‘端口(COM和CPT)’,就会识别到相应的CH340端口。

image.png

image.png

注:每台电脑的端口号都会不一样,只要是识别到了CH340就是我们需要的端口。

二、打开串口助手

1.打开资料中的串口助手软件(UartAssist),设置串口助手的参数,串口号选择K210开发板的串口号,波特率选择115200,校验位选择NONE,数据位选择8,停止位选择1,流控制选择NONE。最后点击‘打开’,点击后会打开串口助手,‘打开’变成了‘关闭’,并且图标黑色变成红色。

image.png

2.先在右下角把串口助手的界面放大,在串口助手底部此时的‘4.DTR’和‘7.RTS’默认是红色的,点击‘4.DTR’和‘7.RTS’,都设置为绿色,然后按一下K210开发板的复位键。如果K210开发板里面的固件没有打印信息,就不会显示内容。

image.png

 2.2 VSCode开发环境搭建

一、编译K210需要的工具

本次我们是在Win10系统下,通过VSCode编辑器搭建K210的开发环境,以下是我们需要用到的工具及简介。

1.CMake:CMake是众多Make工具的一种,具有跨平台,跨编译器等特性,是一种非常实用的工具。

2.Toolchain:交叉编译器Toolchain是用于调试开发板的工具和相关库组合起来的集合,也称为工具链。一般内附有程式编译器(compiler),如GCC,可以进行程式编译、或跨平台编译工作。

3.VSCode:VSCode是Microsoft出品的一款开源代码编辑器,支持多种插件,可扩展性强,具有代码高亮,自动补全等功能。

4.K210-SDK:K210官方出的SDK,是开发K210的基础,里面自带有芯片的各种驱动。

5.flash:K210芯片烧录程序的工具。

二、安装CMake

1.下载CMake

CMake官方下载网址:Download CMake

这里以win10 64位系统为例,点击下载cmake-3.17.2-win64-x64.msi

32位系统则下载win32-x86的版本。

后缀.msi和.zip的区别:.msi文件是安装程序,与普通安装程序差不多,推荐使用此方法;.zip是cmake的程序文件,不需要安装,解压后放到某个路径下,再把路径添加到系统环境变量上就可以使用,一般用于安装多个版本的cmake。

如果出现无法下载的问题,可使用资料中提供的版本,或者使用VPN工具连接后再下载。

image.png

2.双击运行并安装cmake

image.png

image.png

选择添加CMake到系统环境变量,这个必须点击,否则后面得手动添加。第四个是创建桌面图标,如果需要桌面图标请打勾。

image.png

选择安装的路径,可以自己定义,但是不要有中文。

image.png

点击Install,开始安装。

image.png

安装完成。

image.png

3.检查验证CMake

打开CMD命令界面,输入cmake -version,可以看到自己安装的CMake版本号则表示安装成功。

image.png

如果在上面安装的时候没有勾选添加环境变量,或者是下载了.zip后缀的文件,则会出现查找不到cmake命令的错误,此时我们需要手动添加系统环境变量。如果可以正常看到cmake版本号,则不需要进行第4步操作。

4.手动添加系统环境变量

右击桌面‘此电脑’图标,依次点击属性->高级系统设置->环境变量,双击系统变量下的Path,再把自己的CMakebin路径添加到环境变量中,最后点击确定。

image.png

三、安装交叉编译器Toolchain

1.下载勘智版本的toolchain

下载资料中的搭建环境工具,解压后可以得到kendryte-toolchain-win-amd64-8.2.0-20190213.zip

image.png

2.解压toolchain文件

把解压得到kendryte-toolchain文件夹移动到c盘的K210目录下。(当然其他的路径也是可以,只是为了方便管理都放到一起。但是如果移到其他路径,必须记住该路径,因为要添加到环境变量里。)

image.png

image.png

3.添加toolchain到系统环境变量

右击桌面‘此电脑’图标,依次点击属性->高级系统设置->环境变量,双击系统变量下的Path,再把自己的kendryte-toolchainbin路径添加到环境变量中即可。例如我这里添加的是:C:K210/kendryte-toolchain/bin

注意:Win变量路径 

 问题是由于路径中的反斜杠(\)被解释为转义字符,导致CMake无法正确解析路径。这在CMake中是一个常见的问题,因为反斜杠在字符串中有特殊含义。

使用正斜杠(/)代替反斜杠(\
将Windows路径中的反斜杠改为正斜杠。这是最简单的方法,CMake能够正确识别这种格式的路径:

image.png

image.png

4.新建make程序

进入kendryte-toolchainbin路径,找到mingw32-make.exe程序,并且复制粘贴,此时会得到一个叫做mingw32-make 副本.exe的文件,然后把mingw32-make 副本.exe重命名为make.exe。

注意:如果系统没有开启显示文件后缀名,则看到的是mingw32-make,这个没关系,也是同样的复制粘贴并重命名副本为make。

image.png

5.验证交叉编译器toolchain

打开CMD命令行界面,输入make -v,如果可以看到GNU Make的版本则表示安装成功。

image.png

四、安装VSCode编辑器

1.下载VSCode编辑

VSCode官方下载地址:Download Visual Studio Code - Mac, Linux, Windows

可以根据自己系统版本选择,这里选择System Installer 64bit,这样下载的就是exe文件,可以直接安装,并且可以给所有用户使用。

image.png

2.安装VSCode

双击运行下载VSCode安装包文件,

image.png

VSCode的安装路径,可以修改也可以保持默认。

image.png

image.png

以下部分是重点,红色方框第一个和第二个:右击文件和文件夹会出现用VSCode打开的快捷方式;第三个:把VSCode设置为默认文本编辑器,可以不勾选;第四个:表示可以在CMD中输入code命令来打开VSCode。

image.png

image.png

点击完成即可,如果勾选了启动Visual Studio Code,系统会自动打开VSCode。

image.png

五、下载K210软件SDK

K210官方提供两个SDK,一个是裸机版SDK,另一个是freertos系统SDK,我们以裸机版SDK为例。

1.下载K210裸机版SDK

K210裸机版SDK下载地址:

GitHub - kendryte/kendryte-standalone-sdk: Standalone SDK for kendryte K210

点击右边的Clone or download,Download ZIP下载SDK。

image.png

2.下载完成后,把SDK文件移动到C:K210/SDK路径下,并解压。当然放到其他路径下也是可以的,但是要注意路径不可以有中文或者空格等特殊符号。

image.png

3.SDK文件架构简介。

image.png

六、编译程序

1.用VSCode打开SDK

在kendryte-standalone-sdk文件夹右键,然后选择通过Code打开。

image.png

2.查看src路径的hello_world工程的main.c文件。运行时,它会从USB串口打印出数据。

image.png

3.打开VSCode的终端,点击菜单栏上的Terminal->New Terminal。

image.png

注意:如果点击了PROBLEMS这一栏,有可能因为安装了某个插件(比如C/C++),插件检测头文件路径而发生的错误,实际并没有错误,不用理会这里的提示。以TERMINAL终端里输出的信息为准就好。

image.png

4.创建build文件夹并进入

在VSCode终端输入以下命令创建build文件夹,并且进入build,build文件夹用于保存cmake编译产生的文件,也是我们最后要得到的烧录固件的保存路径。

mkdir build

cd build

image.png

5.CMake编译程序

cmake .. -DPROJ=hello_world -G "MinGW Makefiles"

image.png

image.png

6.make编译程序

image.png

image.png

7.查看生成的文件

image.png

// My Bash:反馈成功  里面有warning
PS D:\K210\SDK\kendryte-standalone-sdk-develop\build> make
Scanning dependencies of target nncase
[  2%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/nncase.cpp.obj
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase.cpp:29:6: warning: 'void {anonymous}::kpu_upload_dma(dmac_channel_number_t, const uint8_t*, uint8_t*, size_t, plic_irq_callback_t, void*)' defined but not used [-Wunused-function]
 void kpu_upload_dma(dmac_channel_number_t dma_ch, const uint8_t *src, uint8_t *dest, size_t input_size, plic_irq_callback_t callback, void *userdata)
      ^~~~~~~~~~~~~~
[  4%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/cpu/cpu_ops.cpp.obj
[  6%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/interpreter.cpp.obj
[  9%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/k210/interpreter.cpp.obj
[ 11%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/k210/k210_ops.cpp.obj
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp: In function 'nncase::runtime::kernel_call_result nncase::runtime::k210::kpu_conv2d(nncase::runtime::k210::kpu_conv2d_options&, nncase::runtime::interpreter_t&, nncase::runtime::interpreter_step_t)':
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:130:18: warning: unused variable 'is_depthwise' [-Wunused-variable]
             auto is_depthwise = options.layer.interrupt_enabe.data.depth_wise_layer != 0;
                  ^~~~~~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:135:29: warning: unused variable 'in_shape' [-Wunused-variable]
             runtime_shape_t in_shape { options.batches, in_ch, in_h, in_w };
                             ^~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp: At global scope:
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:96:5: warning: 'int {anonymous}::kpu_dma_plic_thunk(void*)' defined but not used [-Wunused-function]
 int kpu_dma_plic_thunk(void *userdata)
     ^~~~~~~~~~~~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:88:6: warning: 'void {anonymous}::kpu_upload_dma(dmac_channel_number_t, const uint8_t*, uint8_t*, size_t, plic_irq_callback_t, void*)' defined but not used [-Wunused-function]
 void kpu_upload_dma(dmac_channel_number_t dma_ch, const uint8_t *src, uint8_t *dest, size_t input_size, plic_irq_callback_t callback, void *userdata)
      ^~~~~~~~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:73:6: warning: 'void {anonymous}::kpu_conv2d_output(kpu_layer_argument_t&, dmac_channel_number_t, uint8_t*, plic_irq_callback_t, void*)' defined but not used [-Wunused-function]
 void kpu_conv2d_output(kpu_layer_argument_t &layer, dmac_channel_number_t dma_ch, uint8_t *dest, plic_irq_callback_t callback, void *userdata)
      ^~~~~~~~~~~~~~~~~
[ 13%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/kernel_registry.cpp.obj
[ 16%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/neutral/neutral_ops.cpp.obj
In file included from D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\neutral\neutral_ops.cpp:15:
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\include/kernels/neutral/neutral_kernels.h: In function 'void nncase::kernels::neutral::conv2d_transpose(const float*, float*, const float*, const float*, const runtime_shape_t&, int32_t, const runtime_shape_t&, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, const nncase::padding&, const nncase::padding&, const nncase::value_range<float>&)':
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\include/kernels/neutral/neutral_kernels.h:293:43: warning: unused variable 'value' [-Wunused-variable]   
                                     float value = bias[g * g_oc + oc];
                                           ^~~~~
[ 18%] Linking CXX static library libnncase.a
[ 18%] Built target nncase
Scanning dependencies of target kendryte
[ 20%] Building C object lib/CMakeFiles/kendryte.dir/bsp/crt.S.obj
[ 23%] Building C object lib/CMakeFiles/kendryte.dir/bsp/entry.c.obj
[ 25%] Building C object lib/CMakeFiles/kendryte.dir/bsp/entry_user.c.obj
[ 27%] Building C object lib/CMakeFiles/kendryte.dir/bsp/interrupt.c.obj
[ 30%] Building C object lib/CMakeFiles/kendryte.dir/bsp/locks.c.obj
[ 32%] Building C object lib/CMakeFiles/kendryte.dir/bsp/printf.c.obj
[ 34%] Building C object lib/CMakeFiles/kendryte.dir/bsp/sleep.c.obj
[ 37%] Building C object lib/CMakeFiles/kendryte.dir/bsp/syscalls.c.obj
[ 39%] Building C object lib/CMakeFiles/kendryte.dir/drivers/aes.c.obj
[ 41%] Building C object lib/CMakeFiles/kendryte.dir/drivers/apu.c.obj
[ 44%] Building C object lib/CMakeFiles/kendryte.dir/drivers/clint.c.obj
[ 46%] Building C object lib/CMakeFiles/kendryte.dir/drivers/dmac.c.obj
[ 48%] Building C object lib/CMakeFiles/kendryte.dir/drivers/dvp.c.obj
[ 51%] Building C object lib/CMakeFiles/kendryte.dir/drivers/fft.c.obj
[ 53%] Building C object lib/CMakeFiles/kendryte.dir/drivers/fpioa.c.obj
[ 55%] Building C object lib/CMakeFiles/kendryte.dir/drivers/gpio.c.obj
[ 58%] Building C object lib/CMakeFiles/kendryte.dir/drivers/gpiohs.c.obj
[ 60%] Building C object lib/CMakeFiles/kendryte.dir/drivers/i2c.c.obj
[ 62%] Building C object lib/CMakeFiles/kendryte.dir/drivers/i2s.c.obj
[ 65%] Building C object lib/CMakeFiles/kendryte.dir/drivers/iomem.c.obj
[ 67%] Building C object lib/CMakeFiles/kendryte.dir/drivers/kpu.c.obj
[ 69%] Building C object lib/CMakeFiles/kendryte.dir/drivers/plic.c.obj
[ 72%] Building C object lib/CMakeFiles/kendryte.dir/drivers/pwm.c.obj
[ 74%] Building C object lib/CMakeFiles/kendryte.dir/drivers/rtc.c.obj
[ 76%] Building C object lib/CMakeFiles/kendryte.dir/drivers/sha256.c.obj
[ 79%] Building C object lib/CMakeFiles/kendryte.dir/drivers/spi.c.obj
[ 81%] Building C object lib/CMakeFiles/kendryte.dir/drivers/sysctl.c.obj
[ 83%] Building C object lib/CMakeFiles/kendryte.dir/drivers/timer.c.obj
[ 86%] Building C object lib/CMakeFiles/kendryte.dir/drivers/uart.c.obj
[ 88%] Building C object lib/CMakeFiles/kendryte.dir/drivers/uarths.c.obj
[ 90%] Building C object lib/CMakeFiles/kendryte.dir/drivers/utils.c.obj
[ 93%] Building C object lib/CMakeFiles/kendryte.dir/drivers/wdt.c.obj
[ 95%] Linking C static library libkendryte.a
[ 95%] Built target kendryte
Scanning dependencies of target hello_world
[ 97%] Building C object CMakeFiles/hello_world.dir/src/hello_world/main.c.obj
[100%] Linking C executable hello_world
Generating .bin file ...
[100%] Built target hello_world

你在构建过程中看到的警告表明代码中有一些定义但未被使用的函数和变量。虽然警告不会阻止代码编译,但它们可能会指示一些潜在问题,这些问题可能影响性能、可读性或未来的维护。以下是如何处理这些警告及其潜在影响的一些建议:

警告类型及其影响

  1. 未使用的函数

    • 像 kpu_upload_dma 和 kpu_dma_plic_thunk 这样的函数虽然定义了,但在代码中并没有被调用。这可能导致不必要的代码膨胀,并可能使代码库更难维护。
    • 解决方案:如果这些函数不需要,考虑将其删除。如果计划将来使用它们或它们是接口的一部分,您可以考虑注释它们以提高可读性。
  2. 未使用的变量

    • 像 is_depthwise 和 in_shape 这样的变量被声明但未使用。这会使代码显得杂乱,可能会让其他开发者困惑。
    • 解决方案:如果这些变量不是必须的,请将其删除。如果计划将来使用它们,请确保在相关上下文中使用它们。
  3. 性能考虑

    • 虽然未使用的代码不会直接导致运行时错误,但可能会导致更大的二进制文件和增加的内存使用。删除未使用的代码可以帮助优化应用程序的性能。

改进代码质量的步骤

  1. 审查并移除:检查生成警告的代码,评估这些未使用的函数和变量是否必要。如果不必要,则将其删除。

  2. 为将来使用注释:如果计划在未来使用某些函数或变量,可以考虑添加注释以解释它们的预期用途。

  3. 启用编译器标志:可以启用更严格的编译器标志(例如 GCC 的 -Wall 和 -Wextra)以捕获更多警告,有助于提高代码质量。

  4. 代码审查:如果您在团队中工作,可以考虑进行代码审查,讨论警告并就处理它们的最佳方法达成一致。

  5. 测试:进行更改后,请确保运行测试,以验证删除或修改代码不会引入新问题。

结论

像这样的警告不是严重的错误,但处理它们可以导致更清晰、更易维护以及可能更高效的代码。如果您对某些具体的函数或变量不确定,请随时询问更多针对性的建议!

七、烧录程序

1.下载烧录工具

K210的烧录工具为kflash,下载地址:

Releases · kendryte/kendryte-flash-windows · GitHub

选择最新版本下载,当前最新版本为v0.4.1

image.png

2.下载完成后解压放到C:K210K-Flash目录下。

image.png

3.双击打开K-Flash.exe,通过type-C数据线连接电脑与K210开发板。Device选择K210开发板的串口号。

Baud rate选择波特率。

Chip选择烧录到芯片还是烧录到SRAM,如果选择in-Chip则烧录到芯片,开机自动启动,断电保存;选择in-Memory则烧录到SRAM,断电后不会保存。

Firmware选择程序固件(.bin文件),这里我们选择之前编译生成的hello_world.bin文件。

勾选Open terminal after flash表示烧录完成后自动打开终端。

点击Flash开始烧录固件。

image.png

4.烧录完成后会自动打开CMD,并且打印以下信息。

image.png

2.3 VSCode汉化以及添加跳转到函数定义的设置

一、汉化

1、首先打开软件,软件默认是英文配置状态,如图所示:

1610348170664428.png

2、使用快捷键:【Ctrl+Shift+P】,进入如下界面。

1610348366414733.png

3、然后在弹出的界面中,输入【configure language】,然后选择【install additional languages】,选择需要安装的语言包。

1610348411453308.png

4、如需安装中文,点击install即可:

1610348449291137.png

5、安装完毕,再按照前面步骤2跟3一样,进入到搜索栏,输入【configure language】,然后选择【zh-cn】即可(安装完毕后重启生效):

1610348508124084.png

二、设置跳转到函数定义

1、可以先安装一下对应代码的相关插件,我不确定是否这些扩展插件会有影响。输入【C/C++】,然后点击install。

1610348558208770.png

2、安装完毕插件后,按照以下点击

,然后选择【Extension Settings】。

1610348605445220.png

3、然后清空搜索栏,并在搜索栏输入【go to definition】,并找到下边两个选项,将他改成goto即可。

1610348648218811.png

3.1 点亮LED灯

一、实验目的

本节课主要学习K210最基础的功能,FPIOA引脚映射和点亮LED灯

二、实验准备

1.实验元件

LED0和LED

image.png

2.元件特性

LED0为红灯,LED1为绿灯。两颗LED灯都是低电平点亮,高电平熄灭

3.硬件连接

K210开发板出厂默认已经焊接好LED0和LED1。LED0连接的是IO0,LED1连接的是IO17

image.png

image.png

image.png

4.SDK中对应API功能

对应的头文件 gpio.h

通用gpio共8个,使用同一个中断源,可配置输入输出信号,可配置触发IO口总中断,边沿触发和电平触发。每隔IO可以分配到FPIOA上48个管脚之一

为用户提供以下接口:

• GPIO口初始化

• GPIO口输入或输出模式

• GPIO引脚电平高gpio_get_pin:读取GPIO引脚电平

5.什么是FPIOA呢?

FPIOA (现场可编程IO阵列)允许用户将255 个内部功能映射到芯片外围的48 个自由IO 上:

• 支持IO 的可编程功能选择

• 支持IO 输出的8 种驱动能力选择

• 支持IO 的内部上拉电阻选择

• 支持IO 的内部下拉电阻选择

• 支持IO 输入的内部施密特触发器设置

• 支持IO 输出的斜率控制

• 支持内部输入逻辑的电平设置

三、实验原理

LED(Light Emitting Diode)也称为发光二极管,是一种能够将电能转化为可见光的固态的半导体器件,它可以直接把电转化为光。LED的内部是一个半导体晶片,晶片的一端附在一个支架上,一端是负极,另一端连接电源的正极,使整个晶片被环氧树脂封装起来。只需要给正极输入正极电压,负极接地,形成回路就可以点亮LED。

半导体晶片由两部分组成,一部分是P型半导体,在它里面空穴占主导地位,另一端是N型半导体,在这边主要是电子。但这两种半导体连接起来的时候,它们之间就形成一个P-N结。当电流通过导线作用于这个晶片的时候,电子就会被推向P区,在P区里电子跟空穴复合,然后就会以光子的形式发出能量,这就是LED灯发光的原理。而光的波长也就是光的颜色,是由形成P-N结的材料决定的。

四、实验过程

1. 首先根据上面的硬件连接引脚图,K210的硬件引脚和软件功能使用的是FPIOA映射关系。

这里要注意的是程序里操作的都是软件引脚,所以需要先把硬件引脚映射成软件GPIO功能,操作的时候直接操作软件GPIO即可。

image.png

image.png

2.main函数是K210芯片的入口函数,所有程序都从这里开始执行,首先初始化硬件引脚,然后使能GPIO时钟,再设置LED0和LED1为输出模式,接着设置LED0和LED1的电平为高电平,表示熄灭状态。

最后在while循环中每隔一秒切换修改value的值,让LED0和LED1交替点亮。

image.png

3.编译调试,烧录运行

把本课程资料中的gpio_led复制到SDK中的src目录下,

然后进入build目录,运行以下命令编译。

cmake .. -DPROJ=gpio_led -G "MinGW Makefiles"

make

image.png

image.png

image.png

注意:如果点击了PROBLEMS这一栏,有可能因为安装了某个插件(比如C/C++),插件检测头文件路径而发生的错误,实际并没有错误,不用理会这里的提示。以TERMINAL终端里输出的信息为准就好。

image.png

编译完成后,在build文件夹下会生成gpio_led.bin文件。

My comments:

// -- Build files have been written to: D:/K210/SDK/kendryte-standalone-sdk-develop/build
PS D:\K210\SDK\kendryte-standalone-sdk-develop\build> make clean
PS D:\K210\SDK\kendryte-standalone-sdk-develop\build> make
[  2%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/nncase.cpp.obj
make[2]: *** [lib\nncase\CMakeFiles\nncase.dir\build.make:82: lib/nncase/CMakeFiles/nncase.dir/nncase.cpp.obj] Error 1
make[1]: *** [CMakeFiles\Makefile2:190: lib/nncase/CMakeFiles/nncase.dir/all] Error 2
make: *** [Makefile:103: all] Error 2  //   出现上述报错

Q:检测到 #include 错误。请更新 includePath。已为此翻译单元(D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase.cpp)禁用波形曲线。, 无法打开 源 文件 "runtime/NNCASE_TARGET/interpreter.h" (dependency of "C:\Users\shiyu.vscode\extensions\ms-vscode.cpptools-1.22.11-win32-x64\bin\runtime\target_interpreter.h")

A:To fix the include path error, you need to update the include path in your project's configuration file to include the directory where target_interpreter.h is located.


{

    "configurations": [

        {

            "name": "Win32",

            "includePath": [

                "${workspaceFolder}/**",

                "d:/K210/SDK/kendryte-standalone-sdk-develop/include",

                "d:/K210/SDK/kendryte-standalone-sdk-develop/lib"

            ],

            "defines": [

                "_DEBUG",

                "UNICODE",

                "_UNICODE"

            ],

            "windowsSdkVersion": "10.0.18362.0",

            "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.26.28801/bin/Hostx64/x64/cl.exe",

            "cStandard": "c11",

            "cppStandard": "c++17",

            "intelliSenseMode": "windows-msvc-x64"

        }

    ],

    "version": 4

}

???

从您提供的 make 命令输出和编译命令,可以看出在编译 nncase.cpp 时发生了错误,导致 make 失败。为了更好地解决问题,我们可以采取以下步骤来定位和解决错误。

Troubleshooting Steps

  1. 查看详细错误日志

    • CMake 和 make 通常会在终端输出更详细的错误信息,显示在上面的错误消息部分。在运行 make 时,您可以添加 VERBOSE=1 来获取详细信息,例如:

      bash

      make VERBOSE=1

    • 这将导致 make 输出完整的编译命令,帮助您更好地了解出了什么问题。
  2. 检查编译器指令

    • 从输出的信息中,我们可以看到编译器被调用的命令。请确认 $(CXX_DEFINES)$(CXX_INCLUDES), 和 $(CXX_FLAGS) 是否可以被正确展开(即已经正确定义)。
    • 您可以手动替换这几个变量,运行具体的编译命令,看看是否有任何明确的错误。确保它们都包含正确的选项,如:

      bash

      D:\K210\kendryte-toolchain\bin\riscv64-unknown-elf-g++.exe -DDEBUG -I/path/to/include -O2 -o CMakeFiles\nncase.dir\nncase.cpp.obj -c D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase.cpp

  3. 检查文件路径

    • 确保 D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase.cpp 文件存在且没有错误。您可以通过文件浏览器或在命令行中运行以下命令确认文件存在:

      bash

      dir D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase.cpp

  4. 查看相关错误

    • 如果执行编译后依然出现错误,检查并记录实际的编译器错误信息。如果相关错误信息含糊不清,您可以尝试查看 nncase.cpp 的代码,看是否有明显的语法错误或缺少的库定义。
  5. 检查依赖项

    • 确保在编译时所有必需的库和头文件都已经正确安装,并且 CMake 能够找到它们。
    • 如果您的项目依赖于其他第三方库,确认它们的路径是否在 CMakeLists.txt 中正确设置。
  6. 分析 CMakeLists.txt

    • 确保在您的 CMakeLists.txt 文件中已经包含了所有必要的库和头文件。例如:

      cmake

      include_directories(${SDK_ROOT}/third_party/xtl/include ${CMAKE_CURRENT_LIST_DIR}/nncase/include)

获得更具体的错误信息

如果您仍然无法解决问题,请在运行编译命令后,将具体的报错信息贴出来。

//报错日志
D:\K210\CMake\bin\cmake.exe -SD:\K210\SDK\kendryte-standalone-sdk-develop -BD:\K210\SDK\kendryte-standalone-sdk-develop\build --check-build-system CMakeFiles\Makefile.cmake 0
D:\K210\CMake\bin\cmake.exe -E cmake_progress_start D:\K210\SDK\kendryte-standalone-sdk-develop\build\CMakeFiles D:\K210\SDK\kendryte-standalone-sdk-develop\build\CMakeFiles\progress.marks
D:/MinGW/bin/make.exe  -f CMakeFiles\Makefile2 all
make[1]: Entering directory 'D:/K210/SDK/kendryte-standalone-sdk-develop/build'
D:/MinGW/bin/make.exe  -f lib\nncase\CMakeFiles\nncase.dir\build.make lib/nncase/CMakeFiles/nncase.dir/depend
make[2]: Entering directory 'D:/K210/SDK/kendryte-standalone-sdk-develop/build'
D:\K210\CMake\bin\cmake.exe -E cmake_depends "MinGW Makefiles" D:\K210\SDK\kendryte-standalone-sdk-develop D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase D:\K210\SDK\kendryte-standalone-sdk-develop\build D:\K210\SDK\kendryte-standalone-sdk-develop\build\lib\nncase D:\K210\SDK\kendryte-standalone-sdk-develop\build\lib\nncase\CMakeFiles\nncase.dir\DependInfo.cmake --color=
make[2]: Leaving directory 'D:/K210/SDK/kendryte-standalone-sdk-develop/build'
D:/MinGW/bin/make.exe  -f lib\nncase\CMakeFiles\nncase.dir\build.make lib/nncase/CMakeFiles/nncase.dir/build
make[2]: Entering directory 'D:/K210/SDK/kendryte-standalone-sdk-develop/build'
[  2%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/nncase.cpp.obj
ude\runtime\neutral -ID:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\include\targets -ID:\K210\SDK\kendryte-standalone-sdk-develop\lib\utils\include -ID:\K210\SDK\kendryte-standalone-sdk-develop\src\gpio_led -ID:\K210\SDK\kendryte-standalone-sdk-develop\third_party\xtl\include -ID:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase\include  -mcmodel=medany -mabi=lp64f -march=rv64imafc -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fno-zero-initialized-in-bss -ffast-math -fno-math-errno -fsingle-precision-constant -Os -ggdb -std=gnu++17 -Wall -Werror=all -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-multichar -Wextra -Werror=frame-larger-than=32768 -Wno-unused-parameter -Wno-sign-compare -Wno-error=missing-braces -Wno-error=return-type -Wno-error=pointer-sign -Wno-missing-braces -Wno-strict-aliasing -Wno-implicit-fallthrough -Wno-missing-field-initializers -Wno-int-to-pointer-cast -Wno-error=comment -Wno-error=logical-not-parentheses -Wno-error=duplicate-decl-specifier -Wno-error=parentheses   -O2 -o CMakeFiles\nncase.dir\nncase.cpp.obj -c D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase.cpp
make[2]: *** [lib\nncase\CMakeFiles\nncase.dir\build.make:82: lib/nncase/CMakeFiles/nncase.dir/nncase.cpp.obj] Error 1
make[2]: Leaving directory 'D:/K210/SDK/kendryte-standalone-sdk-develop/build'
make[1]: *** [CMakeFiles\Makefile2:190: lib/nncase/CMakeFiles/nncase.dir/all] Error 2
make[1]: Leaving directory 'D:/K210/SDK/kendryte-standalone-sdk-develop/build'
make: *** [Makefile:103: all] Error 2

根据您提供的详细日志信息,make 在编译 nncase.cpp 文件时出现了错误,导致构建失败。以下是对日志的分析以及可能的解决方案:

1. 编译命令概述

日志中的编译命令如下:

bash

D:\K210\kendryte-toolchain\bin\riscv64-unknown-elf-g++.exe -ID:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\include\targets ... -O2 -o CMakeFiles\nncase.dir\nncase.cpp.obj -c D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase.cpp

  • 这个命令尝试使用 RISC-V 编译器编译 nncase.cpp 文件。
  • 其中包含了多个 -I 选项来指定头文件的搜索路径,和一系列编译选项。

2. 错误信息分析

错误信息是:

vbnet

make[2]: *** [lib\nncase\CMakeFiles\nncase.dir\build.make:82: lib/nncase/CMakeFiles/nncase.dir/nncase.cpp.obj] Error 1

这个错误信息表明在尝试编译 nncase.cpp 时发生了错误,但没有提供具体的错误原因。通常情况下,编译器会在终端输出中提供更详细的错误信息,比如语法错误、未定义的符号等。

3. 查找详细错误信息

为了找到具体的错误原因,可以尝试以下步骤:

  • 查看终端输出:在运行 make 时,确保没有被输出的信息被忽略。具体的编译错误通常会在 make 的输出中显示。

  • 手动运行编译命令:将完整的编译命令复制到命令行中手动执行,这样可以直接查看编译器的错误输出。例如:

    bash

    D:\K210\kendryte-toolchain\bin\riscv64-unknown-elf-g++.exe -ID:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\include\targets -ID:\K210\SDK\kendryte-standalone-sdk-develop\lib\utils\include ... -O2 -o CMakeFiles\nncase.dir\nncase.cpp.obj -c D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase.cpp

4. 检查 nncase.cpp 文件

  • 语法错误:打开 nncase.cpp 文件,检查是否有明显的语法错误。
  • 缺少头文件:确保在 nncase.cpp 中使用的所有头文件都可以被找到,并且路径正确。

5. 编译器选项

  • 编译选项:注意到编译命令中使用了多个编译器选项,如 -Werror,这意味着所有警告都将被视为错误。如果 nncase.cpp 中有警告,这可能会导致编译失败。您可以尝试去掉 -Werror,看看是否能够成功编译。

6. 依赖项和库

确保所有依赖项都已正确安装并且可以找到。检查 CMakeLists.txt 中是否包含所有必要的库和头文件。

7. 清理和重新构建

如果您对代码或构建配置进行了任何更改,建议您先清理构建目录,然后重新运行 CMake 和 make:

bash

make clean cmake .. make

8. 提供更详细的错误信息

如果您运行编译命令后仍然遇到错误,请将输出的具体错误信息提供给我,这样我可以更好地帮助您分析问题。 

上述问题;最终发现是RV编译工具链path问题,系统变量名设置了toolchain而不是Path;

将系统变量重新设置在Path下添加对应路径重做一遍OK

//My BASH 反馈日志
PS D:\K210\SDK\kendryte-standalone-sdk-develop\build> make
Scanning dependencies of target nncase
[  2%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/nncase.cpp.obj
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase.cpp:29:6: warning: 'void {anonymous}::kpu_upload_dma(dmac_channel_number_t, const uint8_t*, uint8_t*, size_t, plic_irq_callback_t, void*)' defined but not used [-Wunused-function]
 void kpu_upload_dma(dmac_channel_number_t dma_ch, const uint8_t *src, uint8_t *dest, size_t input_size, plic_irq_callback_t callback, void *userdata)
      ^~~~~~~~~~~~~~
[  4%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/cpu/cpu_ops.cpp.obj
[  6%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/interpreter.cpp.obj
[  9%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/k210/interpreter.cpp.obj
[ 11%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/k210/k210_ops.cpp.obj
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp: In function 'nncase::runtime::kernel_call_result nncase::runtime::k210::kpu_conv2d(nncase::runtime::k210::kpu_conv2d_options&, nncase::runtime::interpreter_t&, nncase::runtime::interpreter_step_t)':
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:130:18: warning: unused variable 'is_depthwise' [-Wunused-variable]
             auto is_depthwise = options.layer.interrupt_enabe.data.depth_wise_layer != 0;
                  ^~~~~~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:135:29: warning: unused variable 'in_shape' [-Wunused-variable]
             runtime_shape_t in_shape { options.batches, in_ch, in_h, in_w };
                             ^~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp: At global scope:
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:96:5: warning: 'int {anonymous}::kpu_dma_plic_thunk(void*)' defined but not used [-Wunused-function]
 int kpu_dma_plic_thunk(void *userdata)
     ^~~~~~~~~~~~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:88:6: warning: 'void {anonymous}::kpu_upload_dma(dmac_channel_number_t, const uint8_t*, uint8_t*, size_t, plic_irq_callback_t, void*)' defined but not used [-Wunused-function]
 void kpu_upload_dma(dmac_channel_number_t dma_ch, const uint8_t *src, uint8_t *dest, size_t input_size, plic_irq_callback_t callback, void *userdata)
      ^~~~~~~~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:73:6: warning: 'void {anonymous}::kpu_conv2d_output(kpu_layer_argument_t&, dmac_channel_number_t, uint8_t*, plic_irq_callback_t, void*)' defined but not used [-Wunused-function]
 void kpu_conv2d_output(kpu_layer_argument_t &layer, dmac_channel_number_t dma_ch, uint8_t *dest, plic_irq_callback_t callback, void *userdata)
      ^~~~~~~~~~~~~~~~~
[ 13%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/kernel_registry.cpp.obj
[ 16%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/neutral/neutral_ops.cpp.obj
In file included from D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\neutral\neutral_ops.cpp:15:
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\include/kernels/neutral/neutral_kernels.h: In function 'void nncase::kernels::neutral::conv2d_transpose(const float*, float*, const float*, const float*, const runtime_shape_t&, int32_t, const runtime_shape_t&, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, const nncase::padding&, const nncase::padding&, const nncase::value_range<float>&)':
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\include/kernels/neutral/neutral_kernels.h:293:43: warning: unused variable 'value' [-Wunused-variable]   
                                     float value = bias[g * g_oc + oc];
                                           ^~~~~
[ 18%] Linking CXX static library libnncase.a
[ 18%] Built target nncase
Scanning dependencies of target kendryte
[ 20%] Building C object lib/CMakeFiles/kendryte.dir/bsp/crt.S.obj
[ 23%] Building C object lib/CMakeFiles/kendryte.dir/bsp/entry.c.obj
[ 25%] Building C object lib/CMakeFiles/kendryte.dir/bsp/entry_user.c.obj
[ 27%] Building C object lib/CMakeFiles/kendryte.dir/bsp/interrupt.c.obj
[ 30%] Building C object lib/CMakeFiles/kendryte.dir/bsp/locks.c.obj
[ 32%] Building C object lib/CMakeFiles/kendryte.dir/bsp/printf.c.obj
[ 34%] Building C object lib/CMakeFiles/kendryte.dir/bsp/sleep.c.obj
[ 37%] Building C object lib/CMakeFiles/kendryte.dir/bsp/syscalls.c.obj
[ 39%] Building C object lib/CMakeFiles/kendryte.dir/drivers/aes.c.obj
[ 41%] Building C object lib/CMakeFiles/kendryte.dir/drivers/apu.c.obj
[ 44%] Building C object lib/CMakeFiles/kendryte.dir/drivers/clint.c.obj
[ 46%] Building C object lib/CMakeFiles/kendryte.dir/drivers/dmac.c.obj
[ 48%] Building C object lib/CMakeFiles/kendryte.dir/drivers/dvp.c.obj
[ 51%] Building C object lib/CMakeFiles/kendryte.dir/drivers/fft.c.obj
[ 53%] Building C object lib/CMakeFiles/kendryte.dir/drivers/fpioa.c.obj
[ 55%] Building C object lib/CMakeFiles/kendryte.dir/drivers/gpio.c.obj
[ 58%] Building C object lib/CMakeFiles/kendryte.dir/drivers/gpiohs.c.obj
[ 60%] Building C object lib/CMakeFiles/kendryte.dir/drivers/i2c.c.obj
[ 62%] Building C object lib/CMakeFiles/kendryte.dir/drivers/i2s.c.obj
[ 65%] Building C object lib/CMakeFiles/kendryte.dir/drivers/iomem.c.obj
[ 67%] Building C object lib/CMakeFiles/kendryte.dir/drivers/kpu.c.obj
[ 69%] Building C object lib/CMakeFiles/kendryte.dir/drivers/plic.c.obj
[ 72%] Building C object lib/CMakeFiles/kendryte.dir/drivers/pwm.c.obj
[ 74%] Building C object lib/CMakeFiles/kendryte.dir/drivers/rtc.c.obj
[ 76%] Building C object lib/CMakeFiles/kendryte.dir/drivers/sha256.c.obj
[ 79%] Building C object lib/CMakeFiles/kendryte.dir/drivers/spi.c.obj
[ 81%] Building C object lib/CMakeFiles/kendryte.dir/drivers/sysctl.c.obj
[ 83%] Building C object lib/CMakeFiles/kendryte.dir/drivers/timer.c.obj
[ 86%] Building C object lib/CMakeFiles/kendryte.dir/drivers/uart.c.obj
[ 88%] Building C object lib/CMakeFiles/kendryte.dir/drivers/uarths.c.obj
[ 90%] Building C object lib/CMakeFiles/kendryte.dir/drivers/utils.c.obj
[ 93%] Building C object lib/CMakeFiles/kendryte.dir/drivers/wdt.c.obj
[ 95%] Linking C static library libkendryte.a
[ 95%] Built target kendryte
Scanning dependencies of target gpio_led
[ 97%] Building C object CMakeFiles/gpio_led.dir/src/gpio_led/main.c.obj
[100%] Linking C executable gpio_led
Generating .bin file ...
[100%] Built target gpio_led

使用type-C数据线连接电脑与K210开发板,打开kflash,选择对应的设备,再将gpio_led.bin文件烧录到K210开发板上。

注意要勾选‘Open terminal after flash’,这样烧录完成固件后就会弹出一个终端可以查看调试的信息

image.png

五、实验现象

LED0和LED1两个灯交替点亮。先亮绿灯1秒,然后绿灯熄灭,红灯亮一秒后熄灭,绿灯再亮起,以此循环。

image.png

image.png

My Comments:红绿交替闪烁,没有问题! 

六、实验总结

1.K210芯片使用FPIOA可编程阵列,所以每次使用硬件IO口前都需要对硬件IO口进行引脚映射。而且在软件中调用的也是软件映射后的软件GPIO。

2.K210芯片与其他单片机芯片同样是从main函数开始运行。

3.使用GPIO前需要设置GPIO的输入输出模式。

4.LED灯是低电平点亮的,给LED引脚设置低电平时点亮,设置高电平时熄灭。

附:API

对应的头文件 gpio.h

gpio_init

描述

初始化GPIO。

函数原型

int gpio_init(void)

返回值

返回值

描述

0

成功

非0

失败

gpio_set_drive_mode

描述

设置GPIO驱动模式。

函数原型

void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode)

参数

参数名称

描述

输入输出

pin

GPIO管脚

输入

mode

GPIO驱动模式

输入

返回值

无。

gpio_set_pin

描述

设置GPIO管脚值。

函数原型

void gpio_set_pin(uint8_t pin, gpio_pin_value_t value)

参数

参数名称

描述

输入输出

pin

GPIO管脚

输入

value

GPIO值

输入

返回值

无。

gpio_get_pin

描述

获取GPIO管脚值。

函数原型

gpio_pin_value_t gpio_get_pin(uint8_t pin)

参数

参数名称

描述

输入输出

pin

GPIO管脚

输入

返回值

获取的GPIO管脚值。

数据类型

相关数据类型、数据结构定义如下:

  • gpio_drive_mode_t:GPIO驱动模式。

  • gpio_pin_value_t:GPIO值。

gpio_drive_mode_t

描述

GPIO驱动模式。

定义

typedef enum _gpio_drive_mode

{

    GPIO_DM_INPUT,

    GPIO_DM_INPUT_PULL_DOWN,

    GPIO_DM_INPUT_PULL_UP,

    GPIO_DM_OUTPUT,

} gpio_drive_mode_t;

成员

成员名称

描述

GPIO_DM_INPUT

输入

GPIO_DM_INPUT_PULL_DOWN

输入下拉

GPIO_DM_INPUT_PULL_UP

输入上拉

GPIO_DM_OUTPUT

输出

gpio_pin_value_t

描述

GPIO 值。

定义

typedef enum _gpio_pin_value

{

    GPIO_PV_LOW,

    GPIO_PV_HIGH

} gpio_pin_value_t;

成员

成员名称

描述

GPIO_PV_LOW

GPIO_PV_HIGH

3.2 点亮RGB灯

一、实验目的

本节课主要学习K210的高速GPIOHS,点亮RGB灯。

二、实验准备

1.实验元件

RGB灯

image.png

2.元件特性

RGB灯可以点亮红色、绿色、蓝灯等颜色,再根据红色绿色蓝色的不同亮度组合成其他颜色,例如黄色、紫色等。

3.硬件连接

K210开发板出厂默认已经焊接好RGB灯。RGB灯R连接的是IO6,G连接的是IO7, B连接的是IO8。

image.png

image.png

4.SDK中对应API功能

对应的头文件 gpiohs.h

高速goiohs总共有32个,可配置输入输出模式,可配置上拉下拉或高阻,每个IO都有单独的中断源,中断支持边沿和电平触发,每个IO都可以自由分配到FPIOA上的48个引脚之一。

为用户提供以下接口:

• gpiohs_set_drive_mode:设置输入输出模式

• gpiohs_set_pin:设置引脚电平

• gpiohs_get_pin:读取引脚电平

• gpiohs_set_pin_edge:设置中断触发电平

• gpiohs_set_irq (0.6.0 后不再支持,请使用gpiohs_irq_register)

• gpiohs_irq_register:注册引脚中断服务

• gpiohs_irq_unregister:注销引脚中断

三、实验原理

RGB灯内部是由三颗颜色分别为红色、绿灯和蓝色的LED组成,所以发光原理与LED是一样的。不同的是三颗LED灯靠得很近,这样就可以设置不同的颜色,来达到展示不同颜色的功能。

四、实验过程

1. 首先根据上面的硬件连接引脚图,K210的硬件引脚和软件功能使用的是FPIOA映射关系。

这里要注意的是程序里操作的都是软件引脚,所以需要先把硬件引脚映射成软件GPIO功能,操作的时候直接操作软件GPIO即可。

image.png

image.png

2.在使用RGB灯前需要初始化,也就是把RGB灯的软件GPIO设置为输出模式。

image.png

3.然后关闭RGB灯,同样是设置RGB灯的GPIO为高电平则可以让RGB灯熄灭。

image.png

4.最后在while循环中每0.5秒修改state的值,从而改变RGB灯的颜色,由于不清楚具体上一次亮的是哪个灯,所以在每次设置灯的颜色前都把RGB灯关闭。state = state % 3;语句的功能是把state的值限制为0,1,2,刚好与软件GPIO对应。

image.png

5.编译调试,烧录运行

把本课程资料中的gpiohs_rgb复制到SDK中的src目录下,

然后进入build目录,运行以下命令编译。

cmake .. -DPROJ=gpiohs_rgb -G "MinGW Makefiles"

make

image.png

编译完成后,在build文件夹下会生成gpiohs_rgb.bin文件。

使用type-C数据线连接电脑与K210开发板,打开kflash,选择对应的设备,再将程序固件烧录到K210开发板上。

PS D:\K210\SDK\kendryte-standalone-sdk-develop\build> make 
Scanning dependencies of target nncase
[  2%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/nncase.cpp.obj
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\nncase.cpp:29:6: warning: 'void {anonymous}::kpu_upload_dma(dmac_channel_number_t, const uint8_t*, uint8_t*, size_t, plic_irq_callback_t, void*)' defined but not used [-Wunused-function]
 void kpu_upload_dma(dmac_channel_number_t dma_ch, const uint8_t *src, uint8_t *dest, size_t input_size, plic_irq_callback_t callback, void *userdata)
      ^~~~~~~~~~~~~~
[  4%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/cpu/cpu_ops.cpp.obj
[  6%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/interpreter.cpp.obj
[  9%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/k210/interpreter.cpp.obj
[ 11%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/k210/k210_ops.cpp.obj
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp: In function 'nncase::runtime::kernel_call_result nncase::runtime::k210::kpu_conv2d(nncase::runtime::k210::kpu_conv2d_options&, nncase::runtime::interpreter_t&, nncase::runtime::interpreter_step_t)':
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:130:18: warning: unused variable 'is_depthwise' [-Wunused-variable]
             auto is_depthwise = options.layer.interrupt_enabe.data.depth_wise_layer != 0;
                  ^~~~~~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:135:29: warning: unused variable 'in_shape' [-Wunused-variable]
             runtime_shape_t in_shape { options.batches, in_ch, in_h, in_w };
                             ^~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp: At global scope:
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:96:5: warning: 'int {anonymous}::kpu_dma_plic_thunk(void*)' defined but not used [-Wunused-function]
 int kpu_dma_plic_thunk(void *userdata)
     ^~~~~~~~~~~~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:88:6: warning: 'void {anonymous}::kpu_upload_dma(dmac_channel_number_t, const uint8_t*, uint8_t*, size_t, plic_irq_callback_t, void*)' defined but not used [-Wunused-function]
 void kpu_upload_dma(dmac_channel_number_t dma_ch, const uint8_t *src, uint8_t *dest, size_t input_size, plic_irq_callback_t callback, void *userdata)
      ^~~~~~~~~~~~~~
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\k210\k210_ops.cpp:73:6: warning: 'void {anonymous}::kpu_conv2d_output(kpu_layer_argument_t&, dmac_channel_number_t, uint8_t*, plic_irq_callback_t, void*)' defined but not used [-Wunused-function]
 void kpu_conv2d_output(kpu_layer_argument_t &layer, dmac_channel_number_t dma_ch, uint8_t *dest, plic_irq_callback_t callback, void *userdata)
      ^~~~~~~~~~~~~~~~~
[ 13%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/kernel_registry.cpp.obj
[ 16%] Building CXX object lib/nncase/CMakeFiles/nncase.dir/runtime/neutral/neutral_ops.cpp.obj
In file included from D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\runtime\neutral\neutral_ops.cpp:15:
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\include/kernels/neutral/neutral_kernels.h: In function 'void nncase::kernels::neutral::conv2d_transpose(const float*, float*, const float*, const float*, const runtime_shape_t&, int32_t, const runtime_shape_t&, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, const nncase::padding&, const nncase::padding&, const nncase::value_range<float>&)':
D:\K210\SDK\kendryte-standalone-sdk-develop\lib\nncase\include/kernels/neutral/neutral_kernels.h:293:43: warning: unused variable 'value' [-Wunused-variable]
                                     float value = bias[g * g_oc + oc];
                                           ^~~~~
[ 18%] Linking CXX static library libnncase.a
[ 18%] Built target nncase
Scanning dependencies of target kendryte
[ 20%] Building C object lib/CMakeFiles/kendryte.dir/bsp/crt.S.obj
[ 23%] Building C object lib/CMakeFiles/kendryte.dir/bsp/entry.c.obj
[ 25%] Building C object lib/CMakeFiles/kendryte.dir/bsp/entry_user.c.obj
[ 27%] Building C object lib/CMakeFiles/kendryte.dir/bsp/interrupt.c.obj
[ 30%] Building C object lib/CMakeFiles/kendryte.dir/bsp/locks.c.obj
[ 32%] Building C object lib/CMakeFiles/kendryte.dir/bsp/printf.c.obj
[ 34%] Building C object lib/CMakeFiles/kendryte.dir/bsp/sleep.c.obj
[ 37%] Building C object lib/CMakeFiles/kendryte.dir/bsp/syscalls.c.obj
[ 39%] Building C object lib/CMakeFiles/kendryte.dir/drivers/aes.c.obj
[ 41%] Building C object lib/CMakeFiles/kendryte.dir/drivers/apu.c.obj
[ 44%] Building C object lib/CMakeFiles/kendryte.dir/drivers/clint.c.obj
[ 46%] Building C object lib/CMakeFiles/kendryte.dir/drivers/dmac.c.obj
[ 48%] Building C object lib/CMakeFiles/kendryte.dir/drivers/dvp.c.obj
[ 51%] Building C object lib/CMakeFiles/kendryte.dir/drivers/fft.c.obj
[ 53%] Building C object lib/CMakeFiles/kendryte.dir/drivers/fpioa.c.obj
[ 55%] Building C object lib/CMakeFiles/kendryte.dir/drivers/gpio.c.obj
[ 58%] Building C object lib/CMakeFiles/kendryte.dir/drivers/gpiohs.c.obj
[ 60%] Building C object lib/CMakeFiles/kendryte.dir/drivers/i2c.c.obj
[ 62%] Building C object lib/CMakeFiles/kendryte.dir/drivers/i2s.c.obj
[ 65%] Building C object lib/CMakeFiles/kendryte.dir/drivers/iomem.c.obj
[ 67%] Building C object lib/CMakeFiles/kendryte.dir/drivers/kpu.c.obj
[ 69%] Building C object lib/CMakeFiles/kendryte.dir/drivers/plic.c.obj
[ 72%] Building C object lib/CMakeFiles/kendryte.dir/drivers/pwm.c.obj
[ 74%] Building C object lib/CMakeFiles/kendryte.dir/drivers/rtc.c.obj
[ 76%] Building C object lib/CMakeFiles/kendryte.dir/drivers/sha256.c.obj
[ 79%] Building C object lib/CMakeFiles/kendryte.dir/drivers/spi.c.obj
[ 81%] Building C object lib/CMakeFiles/kendryte.dir/drivers/sysctl.c.obj
[ 83%] Building C object lib/CMakeFiles/kendryte.dir/drivers/timer.c.obj
[ 86%] Building C object lib/CMakeFiles/kendryte.dir/drivers/uart.c.obj
[ 88%] Building C object lib/CMakeFiles/kendryte.dir/drivers/uarths.c.obj
[ 90%] Building C object lib/CMakeFiles/kendryte.dir/drivers/utils.c.obj
[ 93%] Building C object lib/CMakeFiles/kendryte.dir/drivers/wdt.c.obj
[ 95%] Linking C static library libkendryte.a
[ 95%] Built target kendryte
Scanning dependencies of target gpiohs_rgb
[ 97%] Building C object CMakeFiles/gpiohs_rgb.dir/src/gpiohs_rgb/main.c.obj
[100%] Linking C executable gpiohs_rgb
Generating .bin file ...
[100%] Built target gpiohs_rgb

五、实验现象

RGB灯会亮红灯,0.5秒后亮绿灯,再0.5秒后亮蓝灯,接着0.5秒后再亮红灯,以此循环,每0.5秒切换一次颜色。

image.png

image.png

image.png

按下reset键: 

 

六、实验总结

1.RGB灯与 LED灯的点亮原理是一样的。

2.高速gpiohs每个IO都有单独的中断源,而通用gpio是共享一个总中断源的。

附:API

对应的头文件 gpiohs.h

gpiohs_set_drive_mode

描述

设置GPIO驱动模式。

函数原型
void gpiohs_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode)
参数

参数名称

描述

输入输出

pin

GPIO管脚

输入

mode

GPIO驱动模式

输入

返回值

无。

gpio_set_pin

描述

设置GPIO管脚值。

函数原型
void gpiohs_set_pin(uint8_t pin, gpio_pin_value_t value)
参数

参数名称

描述

输入输出

pin

GPIO管脚

输入

value

GPIO值

输入

返回值

无。

gpio_get_pin

描述

获取GPIO管脚值。

函数原型
gpio_pin_value_t gpiohs_get_pin(uint8_t pin)
参数

参数名称

描述

输入输出

pin

GPIO管脚

输入

返回值

获取的GPIO管脚值。

gpiohs_set_pin_edge

描述

设置高速GPIO中断触发模式。

函数原型
void gpiohs_set_pin_edge(uint8_t pin, gpio_pin_edge_t edge)
参数

参数名称

描述

输入输出

pin

GPIO管脚

输入

edge

中断触发方式

输入

返回值

无。

gpiohs_set_irq

描述

设置高速GPIO的中断回调函数。

函数原型
void gpiohs_set_irq(uint8_t pin, uint32_t priority, void(*func)());
参数

参数名称

描述

输入输出

pin

GPIO管脚

输入

priority

中断优先级

输入

func

中断回调函数

输入

返回值

无。

gpiohs_irq_register

描述

设置高速GPIO的中断回调函数。

函数原型
void gpiohs_irq_register(uint8_t pin, uint32_t priority, plic_irq_callback_t callback, void *ctx)
参数

参数名称

描述

输入输出

pin

GPIO管脚

输入

priority

中断优先级

输入

plic_irq_callback_t

中断回调函数

输入

ctx

回调函数参数

输入

返回值

无。

gpiohs_irq_unregister

描述

注销GPIOHS中断。

函数原型

void gpiohs_irq_unregister(uint8_t pin)
参数

参数名称

描述

输入输出

pin

GPIO管脚

输入

返回值

无。

数据类型

相关数据类型、数据结构定义如下:

·         gpio_drive_mode_t:GPIO驱动模式。

·         gpio_pin_value_t:GPIO值。

·         gpio_pin_edge_t:GPIO边沿触发模式。

gpio_drive_mode_t

描述

GPIO驱动模式。

定义
typedef enum _gpio_drive_mode
{
    GPIO_DM_INPUT,
    GPIO_DM_INPUT_PULL_DOWN,
    GPIO_DM_INPUT_PULL_UP,
    GPIO_DM_OUTPUT,
} gpio_drive_mode_t;
成员

成员名称

描述

GPIO_DM_INPUT

输入

GPIO_DM_INPUT_PULL_DOWN

输入下拉

GPIO_DM_INPUT_PULL_UP

输入上拉

GPIO_DM_OUTPUT

输出

gpio_pin_value_t

描述

GPIO 值。

定义
typedef enum _gpio_pin_value
{
    GPIO_PV_LOW,
    GPIO_PV_HIGH
} gpio_pin_value_t;
成员

成员名称

描述

GPIO_PV_LOW

GPIO_PV_HIGH

gpio_pin_edge_t

描述

高速GPIO边沿触发模式。

定义
typedef enum _gpio_pin_edge
{
    GPIO_PE_NONE,
    GPIO_PE_FALLING,
    GPIO_PE_RISING,
    GPIO_PE_BOTH,
    GPIO_PE_LOW,
    GPIO_PE_HIGH = 8,
} gpio_pin_edge_t;
成员

成员名称

描述

GPIO_PE_NONE

不触发

GPIO_PE_FALLING

下降沿触发

GPIO_PE_RISING

上升沿触发

GPIO_PE_BOTH

双沿触发

GPIO_PE_LOW

低电平触发

GPIO_PE_HIGH

高电平触发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值