Skip to content

Latest commit

 

History

History
1006 lines (785 loc) · 24.2 KB

K510_Linux_Kernel_Driver_Developer_Guides.md

File metadata and controls

1006 lines (785 loc) · 24.2 KB

K510 Linux Kernel Driver Developer's Guide

文档版本:V1.0.0

发布日期:2022-03-09

免责声明 您购买的产品、服务或特性等应受北京嘉楠捷思信息技术有限公司(“本公司”,下同)商业合同和条款的约束,本文档中描述的全部或部分产品、服务或特性可能不在您的购买或使用范围之内。除非合同另有约定,本公司不对本文档的任何陈述、信息、内容的准确性、可靠性、完整性、营销型、特定目的性和非侵略性提供任何明示或默示的声明或保证。除非另有约定,本文档仅作为使用指导的参考。 由于产品版本升级或其他原因,本文档内容将可能在未经任何通知的情况下,不定期进行更新或修改。

商标声明

”、“Canaan”图标、嘉楠和嘉楠其他商标均为北京嘉楠捷思信息技术有限公司的商标。本文档可能提及的其他所有商标或注册商标,由各自的所有人拥有。

版权所有©2022北京嘉楠捷思信息技术有限公司 本文档仅适用K510平台开发设计,非经本公司书面许可,任何单位和个人不得以任何形式对本文档的部分或全部内容传播。

北京嘉楠捷思信息技术有限公司 网址:canaan-creative.com 商务垂询:salesAI@canaan-creative.com

# 前言 **文档目的** 本文档为K510 sdk的配套文档,本文档主要讲linux相关驱动、配置、调试等

读者对象

本文档(本指南)主要适用的人员:

  • 软件开发人员
  • 技术支持人员

修订记录 修订记录累积了每次文档更新的说明。最新版本的文档包含以前所有版本的更新内容。

版本号 修改者 修订日期 修订说明
V1.0.0 系统软件组 2022-03-09 SDK V1.5发布
**目 录**

[TOC]

1 Linux Kernel简介

目前sdk使用的linux版本是4.17.0。Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年10月5日首次发布,它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的Unix工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。Linux有上百种不同的发行版,如基于社区开发的debian、archlinux,和基于商业开发的Red Hat Enterprise Linux、SUSE、Oracle Linux等。

了解更多Linux kernel的相关资料,请访问:

https://docs.kernel.org/

1.1 获取方式

下载并编译sdk,sdk编译的时候会下载并编译linux代码。

sdk的下载编译方法请参考K510_SDK_Build_and_Burn_Guide

1.2开发环境需求

  • 操作系统
编号 软件资源 说明
1 Ubuntu 18.04/20.04
  • 软件环境要求如下表所示:
编号 软件资源 说明
1 K510 SDK v1.5

2 内核默认配置文件及dts

默认的内核配置文件路径:

arch/riscv/configs/k510_defconfig

kernel支持两个开发板 K510 CRB 和EVB,相应的dts文件如下:

arch/riscv/boot/dts/canaan/k510_crb_lp3_v0_1.dts

arch/riscv/boot/dts/canaan/k510_evb_lp3_v1_1.dts

在arch/riscv/boot/dts/canaan/k510_common目录下存放的是soc级公共dts定义。

3调试

3.1 使用JTAG调试linux内核

  1. 安装Andesight v3.2.1

  2. 进入andesight安装目录下ice目录,运行ICEMAN

#ICEman -Z v5 --smp
  1. 使用gdb调试,这里以 /dev/mem 内核代码driver/char/mem.c为例
riscv64-linux-gdb --eval-command="target remote 192.168.200.100:1111"
 (gdb) symbol-file vmlinux
 (gdb) hbreak mmap_mem
  1. 应用程序打开/dev/mem,调用mmap后进入断点

4 驱动说明

4.1 UART

配置选项:

CONFIG_SERIAL_8250_DW

驱动文件:

/tty/serial/8250

设备树:

serial@96000000 {
    status = "okay";
    #address-cells = <0x2>;
    #size-cells = <0x2>;
    compatible = "snps,dw-apb-uart";
    reg = <0x0 0x96000000 0x0 0x100>;
    interrupt-parent = <0x6>;
    interrupts = <0x1 0x4>;
    resets = <0x4 0x58 0x1 0x1f 0x0>;
    reset-names = "uart0_rst";
    power-domains = <0x5 0x6>;
    clock-frequency = <0x17d7840>;
    reg-shift = <0x2>;
    reg-io-width = <0x4>;
    no-loopback-test = <0x1>;
    pinctrl-names = "default";
    pinctrl-0 = <0x1f>;
};

API:设备文件节点:

/dev/ttyS0
/dev/ttyS1/2/3    #目前dts中disable

编程接口:标准串口驱动,参考Linux man page

man termios

4.2 ETH

配置选项:

CONFIG_NET_CADENCE

驱动文件:

drivers/net/ethernet/cadence

设备树:

emac@93030000 {
    status = "okay";
    compatible = "cdns,k510-gem";
    reg = <0x0 0x93030000 0x0 0x10000>;
    interrupt-parent = <0x6>;
    interrupts = <0x36 0x4 0x37 0x4 0x38 0x4>;
    clocks = <0x1b 0x1b 0x1b 0x1b 0x1b 0x1b>;
    clock-names = "hclk", "pclk", "ether_clk", "tx_clk", "rx_clk", "tsu_clk";
    clock-config = <0x97001104>;
    resets = <0x4 0xe4 0x1 0x1f 0x0>;
    reset-names = "emac_rst";
    power-domains = <0x5 0x5>;
    phy-mode = "rgmii";
    pinctrl-names = "default";
    pinctrl-0 = <0x1c>;
};

设备:eth0 Api说明:标准网口驱动,请参考tcp/ip socket编程;

网口ip配置:

ifconfig eth0 xxx.xxx.xxx.xxx

4.3 EMMC

配置选项:

CONFIG_MMC_SDHCI_CADENCE

驱动文件:

drivers/mmc/host/sdhci-cadence.c

设备树:

sdio@93000000 {
    status = "okay";
    compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc";
    reg = <0x0 0x93000000 0x0 0x2000>;
    interrupt-parent = <0x6>;
    interrupts = <0x30 0x4>;
    clocks = <0x14>;
    max-frequency = <0x2faf080>;
    resets = <0x4 0xc8 0x1 0x1f 0x0>;
    reset-names = "sdio0_rst";
    power-domains = <0x5 0x5>;
    bus-width = <0x8>;
    pinctrl-names = "default";
    pinctrl-0 = <0x15>;
};

设备和分区:

[root@k510-test ~ ]$ ls -l /dev/ | grep mmcblk0
brw------- 179,  0 Jan 1 1970 mmcblk0      # emmc
brw------- 179,  8 Jan 1 1970 mmcblk0boot0
brw------- 179, 16 Jan 1 1970 mmcblk0boot1
brw------- 179,  1 Jan 1 1970 mmcblk0p1    # emmc第一个分区(boot)
brw------- 179,  2 Jan 1 1970 mmcblk0p2    # emmc第二个分区(kenrel,env,vfat)
brw------- 179,  3 Jan 1 1970 mmcblk0p3    # emmmc第三个分区(rootfs文件系统,ext2)

驱动API:标准驱动,当成普通文件读写就可以。

4.4 SD CARD

配置选项:

CONFIG_MMC_SDHCI_CADENCE

驱动文件:

drivers/mmc/host/sdhci-cadence.c

设备树:

sdio@93020000 {
    status = "okay";
    compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc";
    reg = <0x0 0x93020000 0x0 0x2000>;
    interrupt-parent = <0x6>;
    interrupts = <0x32 0x4>;
    clocks = <0x19>;
    max-frequency = <0x2faf080>;
    resets = <0x4 0xd0 0x1 0x1f 0x0>;
    reset-names = "sdio2_rst";
    power-domains = <0x5 0x5>;
    bus-width = <0x4>;
    cap-sd-highspeed;
    cdns,phy-input-delay-legacy = <0xf>;
    cdns,phy-input-delay-sd-highspeed = <0xf>;
    pinctrl-names = "default";
    pinctrl-0 = <0x1a>;
};

设备:

[root@k510-test ~ ]$ ls -l /dev/ | grep mmcblk1
brw------- 179, 24 mmcblk1      # sd卡设备
brw------- 179, 25 mmcblk1p1    # sd卡第一个分区(boot,kenrel,env,vfat)
brw------- 179, 26 mmcblk1p2    # sd卡第二个分区(rootfs文件系统,ext2)
brw------- 179, 27 mmcblk1p3    # sd卡第三个分区(用户分区)

驱动API:标准驱动,当成普通文件读写就可以。

4.5 WDT

配置选项:

CONFIG_DW_WATCHDOG

驱动文件:

drivers/watchdog/dw_wdt.c

设备树:

wdt@97010000 {
    status = "okay";
    compatible = "snps,dw-wdt";
    reg = <0x0 0x97010000 0x0 0x100>;
    clocks = <0x44>;
    resets = <0x4 0x40 0x2 0x0 0x3>;
    reset-names = "wdt0_rst";
};

wdt@97020000 {
    status = "okay";
    compatible = "snps,dw-wdt";
    reg = <0x0 0x97020000 0x0 0x100>;
    clocks = <0x45>;
    resets = <0x4 0x40 0x2 0x0 0x4>;
    reset-names = "wdt1_rst";
};

wdt@97030000 {
    status = "okay";
    compatible = "snps,dw-wdt";
    reg = <0x0 0x97030000 0x0 0x100>;
    clocks = <0x46>;
    resets = <0x4 0x40 0x2 0x0 0x5>;
    reset-names = "wdt2_rst";
};

API:设备文件节点:

/dev/watchdog
/dev/watchdog0/1/2

编程接口:linux文件IO(open, close , ioctl),详见Linux man page 内核源码自带文档:Documentation/watchdog/watchdog-api.txt

4.6 PWM

配置选项:

CONFIG_PWM_GPIO
CONFIG_PWM_CANAAN

驱动文件:

drivers/pwm/pwm-canaan.c
drivers/pwm/pwm-gpio.c

设备树:

pwm0@970f0000 {
    status = "okay";
    compatible = "canaan,k510-pwm";
    reg = <0x0 0x970f0000 0x0 0x40>;
    clocks = <0x55>;
    clock-names = "pwm";
    resets = <0x4 0x40 0x2 0x0 0xb>;
    reset-names = "pwm_rst";
    pinctrl-names = "default";
    pinctrl-0 = <0x56>;
};

pwm1@970f0000 {
    status = "okay";
    compatible = "canaan,k510-pwm";
    reg = <0x0 0x970f0040 0x0 0x40>;
    clocks = <0x55>;
    clock-names = "pwm";
    resets = <0x4 0x40 0x2 0x0 0xb>;
    reset-names = "pwm_rst";
    pinctrl-names = "default";
    pinctrl-0 = <0x57>;
};

API:pwm驱动在用户态可以通过sysfs访问, /sys/class/pwm/

编程接口:Linux文件IO(open,read, write),详见Linux man page

内核源码自带文档:Documentation/pwm.txt

4.7 I2C

配置选项:

CONFIG_I2C_DESIGNWARE_CORE
CONFIG_I2C0_TEST_DRIVER

驱动文件:

drivers/misc/canaan/i2c/test-i2c0.c
drivers/i2c/busses/i2c-designware-platdrv.c

设备树:

i2c@97060000 {
    status = "disable";
    compatible = "snps,designware-i2c";
    reg = <0x0 0x97060000 0x0 0x100>;
    interrupt-parent = <0x6>;
    interrupts = <0xc 0x4>;
    clocks = <0x48>;
    clock-frequency = <0x186a0>;
    resets = <0x4 0x40 0x2 0x0 0x0>;
    reset-names = "i2c0_rst";
};

API: I2C驱动属于总线驱动,使用Linux kernel I2C子系统框架实现。用户态可以通过sysfs访问,也可以使用i2c-tools等用户态工具程序。

/sys/bus/i2c/devices/

编程接口:linux文件IO(open,read, write),详见Linux man page 内核源码自带文档:Documentation/i2c/dev-interface

4.8 USB OTG

配置选项:

USB_CANAAN_OTG20

驱动:

drivers/usb/canaan_otg20/core_drv_mod

设备树:

usb@93060000 {
    status = "okay";
    compatible = "Cadence,usb-dev1.00";
    reg = <0x0 0x93060000 0x0 0x10000>;
    interrupt-parent = <0x6>;
    interrupts = <0x2d 0x4 0x2e 0x4>;
    resets = <0x4 0x18c 0x1 0x1f 0x0>;
    reset-names = "usb_rst";
    power-domains = <0x5 0xc>;
    otg_power_supply-gpios = <0x13 0x10 0x0>;
};

USB作为host,可以挂载U盘,作为device,可以当作U盘。

4.9 CLK

配置选项:

CONFIG_COMMON_CLK_CAN_K510

驱动文件:

drivers/reset/canaan/reset-k510.c

设备树:

arch/riscv/boot/dts/canaan/k510_common/clock_provider.dtsi
arch/riscv/boot/dts/canaan/k510_common/clock_consumer.dtsi
  • clock_provider.dtsi中定义所有时钟节点
  • clock_consumer.dtsi中在各个驱动dts节点引用

4.10 POWER

配置选项:

CONFIG_CANAAN_PM_DOMAIN

驱动文件:

drivers/soc/canaan/k510_pm_domains.c

设备树:

arch/riscv/boot/dts/canaan/k510_common/power_provider.dtsi
arch/riscv/boot/dts/canaan/k510_common/power_consumer.dtsi
sysctl_power@97003000 {
    status = "okay";
    compatible = "canaan, k510-sysctl-power";
    reg = <0x0 0x97003000 0x0 0x1000>;
    #power-domain-cells = <0x1>;
    phandle = <0x5>;
};
  • power_provider.dtsi 定义了provider的dts节点
  • include/dt-bindings/soc/canaan,k510_pm_domains.h 中定义了全部电源域
  • power_consumer.dtsi中在驱动各自dts节点中引用

4.11 RESET

配置选项:

CONFIG_COMMON_RESET_K510

驱动文件:

drivers/reset/canaan/reset-k510.c

设备树:

arch/riscv/boot/dts/canaan/k510_common/reset_provider.dtsi
arch/riscv/boot/dts/canaan/k510_common/reset_consumer.dtsi
sysctl_reset@97002000 {
    status = "okay";
    compatible = "canaan,k510-sysctl-reset";
    reg = <0x0 0x97002000 0x0 0x1000>;
    #reset-cells = <0x4>;
    phandle = <0x4>;
};
  • reset_provider.dtsi 定义了provider的dts节点
  • include/ dt-bindings/reset/canaan-k510-reset.h 中定义了全部reset信号
  • reset_consumer.dtsi中在驱动各自dts节点中引用

4.12 PINCTL

配置选项:

CONFIG_PINCTRL_K510

驱动文件:

drivers/pinctrl/canaan

相关设备树:

arch/riscv/boot/dts/canaan/k510_common/iomux_provider.dtsi
arch/riscv/boot/dts/canaan/k510_common/iomux_consumer.dtsi
iomux@97040000 {
    status = "okay";
    compatible = "pinctrl-k510";
    reg = <0x0 0x97040000 0x0 0x1000>;
    resets = <0x4 0x40 0x2 0x0 0x9>;
    reset-names = "iomux_rst";
    #pinctrl-cells = <0x1>;
    pinctrl-k510,register-width = <0x20>;
    pinctrl-k510,function-mask = <0xffffffff>;

    iomux_emac_pins {
        pinctrl-k510,pins = <0x23 0x23012d 0x24 0x24012e 0x22 0x22012c 0x26 0x260132 0x20 0x20012a 0x2e 0x2e013a 0x2d 0x2d0139 0x2a 0x2a0136 0x29 0x290135 0x1d 0x1d0126>;
    };

    iomux_mmc0_pins {
        pinctrl-k510,pins = <0x7 0x70107 0x8 0x80108 0x9 0x90109 0xa 0xa010a 0xb 0xb010b 0xc 0xc010c 0xd 0xd010d 0xe 0xe010e 0xf 0xf010f 0x10 0x100110>;
        phandle = <0x15>;
    };

    iomux_mmc2_pins {
        pinctrl-k510,pins = <0x17 0x170117 0x18 0x180118 0x19 0x190119 0x1a 0x1a011a 0x1b 0x1b011b 0x1c 0x1c011c>;
        phandle = <0x1a>;
    };

    iomux_uart0_pins {
        pinctrl-k510,pins = <0x70 0x54 0x71 0x5a>;
        phandle = <0x1f>;
    };

    iomux_uart1_pins {
        pinctrl-k510,pins = <0x72 0x64 0x73 0x6a>;
        phandle = <0x20>;
    };

    iomux_emac_rgmii_pins {
        pinctrl-k510,pins = <0x23 0x23012d 0x24 0x24012e 0x1d 0x1d0123 0x26 0x260131 0x2e 0x2e013a 0x2d 0x2d0139 0x2c 0x2c0138 0x2b 0x2b0137 0x1e 0x1e0128 0x25 0x25012f 0x2a 0x2a0136 0x29 0x290135 0x28 0x280134 0x27 0x270133>;
        phandle = <0x1c>;
    };

    iomux_i2s_pins {
        pinctrl-k510,pins = <0x64 0xab 0x65 0xad 0x63 0xa3 0x62 0x93>;
        phandle = <0x22>;
    };

    iomux_i2c1_pins {
        pinctrl-k510,pins = <0x78 0x44 0x79 0x45>;
        phandle = <0x4a>;
    };

    iomux_i2c2_pins {
        pinctrl-k510,pins = <0x67 0x46 0x66 0x47>;
        phandle = <0x4d>;
    };

    iomux_i2c3_pins {
        pinctrl-k510,pins = <0x74 0x49 0x75 0x48>;
        phandle = <0x4f>;
    };

    iomux_i2c4_pins {
        pinctrl-k510,pins = <0x30 0x4b 0x2f 0x4a>;
        phandle = <0x52>;
    };

    iomux_dvp_pins {
        pinctrl-k510,pins = <0x33 0x33013f 0x34 0x340140 0x35 0x350141 0x36 0x360142 0x37 0x370143 0x38 0x380144 0x39 0x390145 0x3a 0x3a0146 0x3b 0x3b0147 0x3c 0x3c0148 0x3d 0x3d0149 0x3e 0x3e014a 0x3f 0x3f014b 0x40 0x40014c 0x42 0x42014e>;
        phandle = <0x6c>;
    };

    iomux_gpio_pins {
        pinctrl-k510,pins = <0x20 0x20 0x22 0x1f 0x45 0xc 0x46 0xd 0x47 0xe 0x4b 0xf 0x4c 0x10 0x4d 0x11 0x4e 0x1d 0x4f 0x1e 0x50 0x14 0x51 0x15 0x53 0x16 0x54 0x17 0x55 0x18 0x61 0x19 0x7b 0x1a>;
        phandle = <0x47>;
    };

    iomux_pwm0_pins {
        pinctrl-k510,pins = <0x7e 0xb3>;
        phandle = <0x56>;
    };

    iomux_pwm1_pins {
        pinctrl-k510,pins = <0x7f 0xb7>;
        phandle = <0x57>;
    };

    iomux_spi0_pins {
        pinctrl-k510,pins = <0x56 0x560162 0x57 0x570163 0x58 0x580164 0x59 0x590165 0x5a 0x5a0166 0x5b 0x5b0167>;
        phandle = <0xc>;
    };

    iomux_spi1_pins {
        pinctrl-k510,pins = <0x68 0x8 0x69 0x9 0x6a 0x0 0x6b 0x1>;
        phandle = <0xf>;
    };

    iomux_spi2_pins {
        pinctrl-k510,pins = <0x7a 0x2a>;
        phandle = <0x12>;
    };

    iomux_mmc1_pins {
        pinctrl-k510,pins = <0x11 0x110111 0x12 0x120112 0x13 0x130113 0x14 0x140114 0x15 0x150115 0x16 0x160116>;
        phandle = <0x17>;
    };
};

iomux_provider.dtsi 定义了provider的dts节点 include/include/dt-bindings/pinctrl/k510.h中定义了全部IO function number iomux_consumer.dtsi中在驱动各自dts节点中引用

4.13 H264

配置选项:

CONFIG_ ALLEGRO_CODEC_DRIVER

驱动文件:

drivers/media/platform/canaan/al5r

相关设备树:

h264@92740000 {
    status = "okay";
    compatible = "al,al5r";
    reg = <0x0 0x92740000 0x0 0x10000>;
    interrupt-parent = <0x6>;
    interrupts = <0x3f 0x4>;
    clocks = <0x7f>;
    resets = <0x4 0x184 0x1 0x1f 0x0>;
    reset-names = "h264_rst";
    power-domains = <0x5 0xb>;
};

API: 设备文件节点: /dev/h264-codec

编程接口: linux文件IO(open, close , ioctl),详见Linux man page

支持的IOCTL命令:

#define AL_CMD_IP_WRITE_REG    _IOWR('q', 10, struct al5_reg)
#define AL_CMD_IP_READ_REG     _IOWR('q', 11, struct al5_reg)
#define AL_CMD_IP_WAIT_IRQ     _IOWR('q', 12, int)
#define AL_CMD_IP_IRQ_CNT      _IOWR('q', 13, int)
#define AL_CMD_IP_CLR_IRQ      _IOWR('q', 14, int)

示例代码:package/h264_demo/src

4.14 DSP

配置选项:

CONFIG_ K510_DSP_DRIVER

驱动文件:

drivers/misc/canaan/k510-dsp

相关设备树:

dsp@99800000 {
    status = "okay";
    compatible = "k510-dsp";
    reg = <0x0 0x99800000 0x0 0x80000>;
    resets = <0x4 0x14 0x0 0x1e 0x0>;
    reset-names = "dsp_rst";
    power-domains = <0x5 0x1>;
    sysctl-phy-addr = <0x97000000>;
};

API: 设备文件节点: /dev/k510-dsp

编程接口: linux文件IO(open, close , ioctl),详见Linux man page

支持的ioctl命令:

#define DSP_CMD_BOOT       _IOWR('q', 1, unsigned long)

示例代码:

package/dsp_app/src/
package/dsp_app_evb_lp3_v1_1/src/

4.15 GNNE

配置选项:

CONFIG_ K510_GNNE_DRIVER

驱动文件:

drivers/misc/canaan/gnne

相关设备树:

gnne@94000000 {
    status = "okay";
    compatible = "k510-gnne";
    reg = <0x0 0x94180000 0x0 0x80000>;
    interrupt-parent = <0x6>;
    interrupts = <0x27 0x4>;
    resets = <0x4 0x2c 0x1 0x1f 0x0>;
    reset-names = "gnne_rst";
    power-domains = <0x5 0x3>;
};

API: 设备文件节点:/dev/k510-gnne 编程接口: linux文件IO(open, close , ioctl),详见Linux man page 支持的ioctl命令:

#define GNNE_ENABLE                   _IOWR('g', 1, unsigned long)
#define GNNE_RESET                    _IOWR('g', 2, unsigned long)
#define GNNE_DISABLE                  _IOWR('g', 3, unsigned long)
#define GNNE_SET_PC                   _IOWR('g', 4, unsigned long)
#define GNNE_SET_MEM_BASE             _IOWR('g', 5, unsigned long)
#define GNNE_GET_STATUS               _IOWR('g', 10, unsigned long)
#define GNNE_SET_PC_ENABLE            _IOWR('g', 11, unsigned long)
#define GNNE_SET_MEM0                 _IOWR('g', 12, unsigned long)
#define GNNE_SET_MEM1                 _IOWR('g', 13, unsigned long)
#define GNNE_SET_MEM2                 _IOWR('g', 14, unsigned long)
#define GNNE_SET_MEM3                 _IOWR('g', 15, unsigned long)
#define GNNE_GET_PC                   _IOWR('g', 16, unsigned long)
#define GNNE_GET_CTRL                 _IOWR('g', 17, unsigned long)
#define GNNE_GET_DSP_INTR_MASK        _IOWR('g', 18, unsigned long)
#define GNNE_GET_MEM0                 _IOWR('g', 19, unsigned long)
#define GNNE_GET_MEM1                 _IOWR('g', 20, unsigned long)
#define GNNE_GET_MEM2                 _IOWR('g', 21, unsigned long)
#define GNNE_GET_MEM3                 _IOWR('g', 22, unsigned long)
#define GNNE_GET_LOAD_STROE_PC_ADDR   _IOWR('g', 23, unsigned long)
#define GNNE_GET_TCU_MFU_PC_ADDR      _IOWR('g', 24, unsigned long)
#define GNNE_GET_CCR_STATUS0          _IOWR('g', 25, unsigned long)
#define GNNE_GET_CCR_STATUS1          _IOWR('g', 26, unsigned long)
#define GNNE_GET_CCR_STATUS2          _IOWR('g', 27, unsigned long)
#define GNNE_GET_CCR_STATUS3          _IOWR('g', 28, unsigned long)

示例代码:

package/nncase_demo/src/mobilenetv2

4.16 TWOD

配置选项:

CONFIG_K510_2D_DRIVER

驱动文件:

drivers/media/platform/canaan/kendryte_2d.c

相关设备树:

twod@92720000 {
    status = "okay";
    compatible = "k510, kendrty_2d";
    reg = <0x0 0x92720000 0x0 0x10000>;
    interrupt-parent = <0x6>;
    interrupts = <0x44 0x0>;
    clocks = <0x6f 0x70>;
    clock-names = "twod_apb", "twod_axi";
};

API: 设备文件节点:/dev/kendryte_2d 编程接口: linux文件IO(open, close , ioctl),详见Linux man page 支持的ioctl命令:

#define KENDRTY_2DROTATION_90     _IOWR('k', 0, unsigned long)
#define KENDRTY_2DROTATION_270    _IOWR('k', 1, unsigned long)

#define KENDRTY_2DROTATION_INPUT_ADDR     _IOWR('k', 2, unsigned long)
#define KENDRTY_2DROTATION_OUTPUT_ADDR    _IOWR('k', 3, unsigned long)
#define KENDRTY_2DROTATION_GET_REG_VAL    _IOWR('k', 4, unsigned long)

4.17 AES和SHA

配置选项:

CONFIG_CRYPTO_DEV_KENDRYTE_CRYP

驱动文件:

drivers/crypto/kendryte/kendryte-aes.c
drivers/crypto/kendryte/kendryte-aes.h
drivers/crypto/kendryte/kendryte-hash.c
drivers/crypto/kendryte/kendryte-hash.h

相关设备树:

aes@91000000 {
    status = "okay";
    compatible = "canaan,k510-aes";
    reg = <0x0 0x91000000 0x0 0x10000>;
    clocks = <0x7>;
    resets = <0x4 0x9c 0x1 0x1f 0x0>;
    reset-names = "aes_rst";
    power-domains = <0x5 0x4>;
    dmas = <0x8 0x1 0xfff 0x0 0x21 0x8 0x1 0xfff 0x0 0x22>;
    dma-names = "tx", "rx";
};

sha@91010000 {
    status = "okay";
    compatible = "canaan,k510-sha";
    reg = <0x0 0x91010000 0x0 0x10000>;
    clocks = <0x9>;
    resets = <0x4 0x94 0x1 0x1f 0x0>;
    reset-names = "sha_rst";
    power-domains = <0x5 0x4>;
    dmas = <0x8 0x1 0xfff 0x0 0x20>;
    dma-names = "tx";
};

API: 设备节点文件: /sys/bus/platform/devices/91000000.aes /sys/bus/platform/devices/91010000.sha

编程接口: 用户态程序使用socket访问内核的驱动API,参考文档位于/Documentation/crypto/userspace-if.rst

示例代码:

package/crypto_demo/src

4.18 温度监测——thermal

配置选项

CONFIG_THERMAL
CONFIG_CANAAN_THERMAL

驱动文件

drivers/thermal/canaan_thermal.c

相关设备树

tsensor@970e0300 {
    status = "okay";
    compatible = "canaan,k510-tsensor";
    reg = <0x0 0x970e0300 0x0 0x100>;
    interrupt-parent = <0x6>;
    interrupts = <0x1c 0x4>;
    clocks = <0x54>;
};

使用方法

cd /sys/class/thermal/thermal_zone0/
echo enabled > mode
cat temp

4.19 2D 旋转——twod

配置选项

CONFIG_KENDRYTE_TWOD_SUPPORT
CONFIG_KENDRYTE_TWOD

驱动文件

drivers/video/canaan/twod/kendryte_td.c
drivers/video/canaan/twod/kendryte_td_reg.c
drivers/video/canaan/twod/kendryte_td.h
drivers/video/canaan/twod/kendryte_td_table.h

相关设备树

twod@92720000 {
    status = "okay";
    compatible = "k510, kendrty_2d";
    reg = <0x0 0x92720000 0x0 0x10000>;
    interrupt-parent = <0x6>;
    interrupts = <0x44 0x0>;
    clocks = <0x6f 0x70>;
    clock-names = "twod_apb", "twod_axi";
};

5 注意事项