3. Kernel development

3.1. GPIO configuration and use

GPIO, the full name of General-Purpose Input/Output, is a general-purpose pin that can be dynamically configured and controlled during software operation.

The following is an example of controlling the LEDs of ROC-RK3399-PC Pro. For other devices, the method is similar.

The main control of ROC-RK3399-PC Pro is RK3399, RK3399 has 5 groups of GPIO bank: GPIO0~GPIO4, each group is divided by A0~A7, B0~B7, C0~C7, D0~D7 as the number.

3.1.1. GPIO number calculation

The ROC-RK3399-PC Pro has two LEDs onboard as follows:

_images/gpio_led_1.png

The DIY_LED net is connected to pin GPIO0_B5:

_images/gpio_led_2.png

PIO pin calculation formula:

pin = bank * 32 + number

GPIO group number calculation formula:

number = group * 8 + X

For example GPIO0_B5:

bank = 0; // GPIO0_B5 => 0, bank ∈ [0,4]
group = 1; // GPIO0_B5 => 1, group ∈ {(A=0), (B=1), (C=2), (D=3)}
X = 5; // GPIO0_B5 => 5, X ∈ [0,7]
number = group * 8 + X = 1 * 8 + 5 = 13;
pin = bank * 32 + number = 0 * 32 + 13 = 13;

Note: This pin is occupied by the LED subsystem by default in the officially released firmware, so first you need to find the following node to disable it!

The ROC-RK3399-PC Pro is defined in arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi:

user {
        status = "disabled"; // add this line
        label = "firefly:yellow:user";
        linux,default-trigger = "ir-user-click";
        default-state = "off";
        gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
        pinctrl-names = "default";
        pinctrl-0 = <&led_user>;
};

Then compile and reprogram the kernel firmware.

3.1.2. User mode uses GPIO

  1. Apply for GPIO

echo 13 > /sys/class/gpio/export
  1. Configure the pin direction

Check out the default pin orientation:

cat /sys/class/gpio/gpio13/direction

Configured as output direction:

echo out > /sys/class/gpio/gpio13/direction
  1. Configure pin output level

As can be seen from the previous schematic diagram, the output high level is to turn on the LED:

echo 1 > /sys/class/gpio/gpio13/value

To turn off the LED:

echo 0 > /sys/class/gpio/gpio13/value

3.1.3. Device tree using GPIO

To configure GPIO in the device tree, you need to configure the function multiplexing and electrical properties of the pins

For rockchip pins, the configuration is as follows:

rockchip,pins = <PIN_BANK PIN_BANK_IDX MUX &phandle>

in:

  • PIN_BANK: the bank where the pin is located

  • PIN_BANK_IDX: the pin number of the bank where the pin is located

  • MUX: function multiplexing configuration, 0 means common GPIO, 1-N means special function multiplexing

  • phandle: pin general configuration, such as internal pull-ups, current strength, etc., described in the Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt file

Configure the GPIO0_B5 pin:

rockchip,pins = <0 13 RK_FUNC_GPIO &pcfg_pull_none>;

Meaning here:

  1. PIN_BANK equals 0

  2. PIN_BANK_IDX equals 13

  3. RK_FUNC_GPIO means to use normal GPIO function

  4. pcfg_pull_none represents normal configuration

For LEDs, Linux defines a set of GPIO subsystems, and the configuration of the device tree is as follows:

/ {
	gpio_led: gpio-led {
		compatible = "gpio-leds";

		diy_led: diy-led {
			label = "diy-led";
			default-state = "on"; // 默认打开
			linux,default-trigger = "default-on"; // 默认触发
			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; // 引脚设置
			pinctrl-names = "default";
			pinctrl-0 = <&diy_led_pin>; // 引用 pinctrl
		};
	};
};

&pinctrl {
	gpio-led-pin {
		diy_led_pin: diy-led-pin {
			rockchip,pins =
				<0 13 RK_FUNC_GPIO &pcfg_pull_none>;
		};
	};
};

Then compile and re-program the kernel firmware, reboot the system and you will see that the LED is lit by default.

If you want the LED to have a blinking effect, you can modify the linux,default-trigger property to achieve:

linux,default-trigger = "timer";

After configuring this property, the LED blinks every 500ms interval by default.

For more property configuration, please refer to Documentation/devicetree/bindings/leds/leds-gpio.txt.

The above device tree configuration can be found in arch/arm64/boot/dts/rockchip/firefly-gpio-demo.dtsi! Users who need it can include this file in the board device tree (remember to disable the conflicting part in rk3399-roc-pc.dtsi first):

#include "firefly-gpio-demo.dtsi"

3.2. ADB configuration and use

3.2.1. Kernel configuration

In the kernel directory, open the kernel configuration options menu:

make firefly_linux_defconfig
make menuconfig

After entering the kernel configuration menu, select in turn: Device Drivers -> USB Support -> USB Gadget Support.

Select USB functions configurable through configfs in the USB Gadget Driver option.

At the same time, select Function filesystem (FunctionFS).

<*> USB Gadget Drivers (USB functions configurable through configfs) --->
        USB functions configurable through configfs
[*] Function filesystem (FunctionFS)

Then compile the kernel in the kernel directory:

make rk3568-firefly.img -j12

After the compilation is completed, burn the kernel to the board. For the burn process, please refer to the Upgrade Firmware page of the corresponding board wiki.

3.2.2. ADB connection

After installing ADB, connect the device and PC with a Micro USB OTG cable. Then use the command adb devices to see if there is a device connected:

firefly@Desktop:~$ adb devices
List of devices attached
0123456789ABCDEF device

From the returned information, you can see that the device has been found, indicating that the device has been successfully connected.

After the device is successfully connected, enter the command adb shell to enter the command line mode:

firefly@Desktop:~$ adb shell
#

In this state, the current path of the command line cannot be seen, and the Tab key completion function is invalid. You need to enter a user to operate normally.

firefly@Desktop:~$ adb shell
# su firefly
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

firefly@firefly:/$
# The command line can be used normally here

The user can also use the command adb shell /bin/bash, or enter the normal command line mode.

You can enter adb help to view the command line help information. Note that not all commands are available. The help information is for reference only.