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:
The DIY_LED net is connected to pin GPIO0_B5:
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¶
Apply for GPIO
echo 13 > /sys/class/gpio/export
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
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 locatedPIN_BANK_IDX
: the pin number of the bank where the pin is locatedMUX
: function multiplexing configuration,0
means common GPIO,1-N
means special function multiplexingphandle
: pin general configuration, such as internal pull-ups, current strength, etc., described in theDocumentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
file
Configure the GPIO0_B5 pin:
rockchip,pins = <0 13 RK_FUNC_GPIO &pcfg_pull_none>;
Meaning here:
PIN_BANK
equals0
PIN_BANK_IDX
equals13
RK_FUNC_GPIO
means to use normal GPIO functionpcfg_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.