开发环境的搭建

获取ubuntu系统镜像

  • 下载好后解压缩虚拟机系统镜像压缩包,解压缩完成后,可以看到里面有如下两个文件,接下来我们会使用后缀名为 .vmx这个 配置文件。

  • 接下来打开已经安装好的 vmware workstation 软件 点击左上角的 文件打开 找到上面的 Ubuntu_18.04.6_VM_LinuxVMImages.COM.vmx 文件,之后会弹出新的虚拟机对话框页面。

  • 如下图所示为我们已经虚拟机的配置界面,我们可以点击红框 2编辑虚拟机设置里面去调整我们虚拟机的内存大小和处理器个数,建议最好内存为 4GB 及以上,处理器至少4 个。 调整好以后,就可以点击 开启此虚拟机 来运行此虚拟机了。

  • 第一次打开会提示一个虚拟机已经复制的对话框,我们这时,只需要点击 我已复制虚拟机 就可以继续启动虚拟机系统了。

  • 等待数秒,系统就会自动启动了,启动以后鼠标点击 Ubuntu 字样,就可以进入登录对话框,输入密码 ubuntu 即可登录进入ubuntu系统内。

    [!NOTE]

    Ubuntu默认的用户名密码分别为 ubuntu ubuntu

  • 如果你发现你的ubuntu虚拟机第一次启动无法通过 windows下复制命令粘贴到ubuntu内,则需要先手敲执行如下命令安装一个用于虚拟机和 windows共享剪切板的工具包。

    1
    2
    sudo apt install open-vm-tools-desktop
    sudo apt install open-vm-tools

    安装完成后,输入sudo reboot,重启ubuntu系统。

  • 也可以使用MobaXterm工具连接ubuntu虚拟机,首先使用ifconfig命令查看虚拟机的ip地址,主机打开MobaXterm使用SSH对虚拟机进行连接,并使用其命令行进行开发。

工具软件安装

  • 接下来介绍一个用于主机和虚拟机传输文件的工具FileZilla,下载安装后打开界面,填入虚拟机ip、用户名、密码和端口后点击连接即可连接上虚拟机进行文件的传输,这里我分别填入了192.168.5.134unbuntuubuntu22,根据自己虚拟机的实际情况来填写,接下来我们就可以愉快地给虚拟机传输文件啦~

  • 下载基于全志t113(BingPi M2)的开发板资料,得到以下资料。

  • 进入到以下文件夹,将install_tools.sh移动到虚拟机内任意文件夹,并在该文件夹路径下执行软件安装脚本./install_tools.sh。

    [!NOTE]

    执行sh安装脚本后,所有的工具软件会自动安装,中间无需任何操作,仅在安装结束出现选择的时候,选择NO。

  • 而后将Tina_Linux_SDK移动到虚拟机里,放入/home/ubuntu路径下,这里我将其目录命名为Tina_Linux_SDK,如下图所示

  • 至此开发环境已搭建完毕!!(想啥呢,才刚刚开始呢👀)

第一次对Tina_Linux_SDK进行编译(测试开发环境是否有问题)

  • 获取环境变量

    在Tina_Linux_SDK目录下,打开终端并输入

    1
    source build/envsetup.sh
  • 选择硬件方案

    1
    lunch

    这里我们选择 6,即 t113_bingpi_m2-tina

  • 编译

    1
    2
    make
    mboot
  • 打包

    1
    pack

    生成的 img 格式的固件在 out/t113-bingpi-m2/tina_t113-bingpi_m2_uart3.img。

  • 常见错误

    此报错说明boot-resource.fex分区设置值小了,需要修改分区配置文件调大一些,一般根据提示修改即可,将小值改大一些,此处将 1512 改为 2336。(具体根据自己实际提示修改)分区配置文件所在位置:

    Tina-Linux/device/config/chips/t113/configs/bingpi_m2/sys_partition.fex

  • Tina配置

    如果需要配置此项请在make编译之前执行,否则忽略,此处为配置 tina 环境(根文件系统)

    1
    make menuconfig
  • 内核配置

    如果需要配置此项请在make编译之前执行,否则忽略,此处为配置系统内核

    1
    make kernel_menuconfig

按键控制LED亮灭应用开发

input子系统介绍

  • input 就是输入的意思,因此 input 子系统就是管理输入的子系统,和 pinctrl、gpio 子系统一样,都是 Linux 内核针对某一类设备而创建的框架。比如按键输入、键盘、鼠标、触摸屏等等这些都属于输入设备,不同的输入设备所代表的含义不同,按键和键盘就是代表按键信息,鼠标和触摸屏代表坐标信息,因此在应用层的处理就不同,对于驱动编写者而言不需要去关心应用层的事情,我们只需要按照要求上报这些输入事件即可。为此input 子系统分为 input 驱动层、input 核心层、input 事件处理层,最终给用户空间提供可访问的设备节点,input 子系统框架如图所示:

配置按键驱动

  • 使能内核按键驱动

    在选择好硬件方案后执行下面的命令进入到菜单

    1
    make kernel_menuconfig

    在菜单中选择GPIO Buttons选项并输入y将其选择。其路径如下:

    1
    2
    3
    4
    5
    -> Device Drivers 
    -> Input device support
    -> Generic input layer (needed for keyboard, mouse, ...) (INPUT [=y])
    -> Keyboards (INPUT_KEYBOARD [=y])
    ->GPIO Buttons

  • 修改设备树

    其设备树文件路径在/home/ubuntu/Tinu_Linux_SDK/device/config/chips/t113/configs/bingpi_m2/board.dts,进入设备树文件后,在其根节点下添加如下

    [!IMPORTANT]

    参数说明:

    compatible:用于匹配驱动。

    status:是否加载设备。

    user_key:每一个按键都是单独的一份配置,需要分别区分开来。(这个命名是自定义的)

    gpios:GPIO 口配置。(根据硬件原理图的GPIO来配置)

    linux,code:这个按键对应的 input 键值。(这个值随意取,读键值的时候用于区分是哪个键,多个键的时候不要一样就好了)

    label:单个按键对应的标签。

    debounce-interval:消抖时间,单位为 us。

    wakeup-source:是否作为唤醒源,配置了这个项的按键可以作为唤醒源唤醒系统。

  • 重新编译、烧录

    修改好内核配置后,执行make -j2make重新编译,编译成功后pack进行打包成img镜像文件通过SD card的方式烧录到开发板上。

编写应用程序进行测试

  • 在ubuntu虚拟机中,进入Sina_Linux_SDK目录,使用sudo mkdir code新建名为code文件夹,使用sudo touch test.c新建名为test的c文件,而后向其中添加如下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <linux/input.h>
    #include <sys/ioctl.h>

    int main(int argc, char *argv[])
    {
    struct input_event in_ev = {0};
    int fd,gd = -1;
    int value = -1;
    char led_on = 0, led_off = 1;

    /* 校验传参 */
    if (2 != argc) {
    fprintf(stderr, "usage: %s <input-dev>\n", argv[0]);
    exit(-1);
    }

    /* 打开文件 */
    if (0 > (fd = open(argv[1], O_RDONLY))) {
    perror("open error");
    exit(-1);
    }
    gd = open("/dev/led", O_RDWR); //打开led驱动程序
    if (gd < 0)
    {
    perror("open usr led error\n");
    }

    for ( ; ; ) {

    /* 循环读取数据 */
    if (sizeof(struct input_event) !=
    read(fd, &in_ev, sizeof(struct input_event))) {
    perror("read error");
    exit(-1);
    }

    if (EV_KEY == in_ev.type) { //按键事件
    switch (in_ev.value) {
    case 0:
    {printf("code<%d>: Key Up\n", in_ev.code);write(gd, &led_off, 1);} //抬起按键时灯灭
    break;
    case 1:
    {printf("code<%d>: Key Down\n", in_ev.code);write(gd, &led_on, 1);} //按下按键时灯亮
    break;
    case 2:
    printf("code<%d>: Long_Press\n", in_ev.code);
    break;
    }
    }
    }
    }
  • 使用交叉编译工具对test.c文件进行编译,生成名为test的可执行文件。

    1
    sudo /home/ubuntu/Tinu_Linux_SDK/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-musl/toolchain/bin/arm-openwrt-linux-gcc -o test test.c
  • 编译完成后,虚拟机通过OTG口连接开发板,并使用adb工具(如果没安装的话,使用sudo apt install adb进行安装)来将可执行文件test上传至开发板中,具体操作如下:

    进入code目录下执行adb push test /opt,将test可执行文件上传至开发板的Linux系统下的opt目录中,执行adb shell进入到开发板的命令行中,cd opt进入opt目录,在该目录执行./test /dev/input/event2,因为我这里输入按键初始化为event2,所以后面参数填的是/dev/input/event2,实际根据自己情况来填。

    执行后即可看到通过按下按键即可点亮LED灯,抬起按键即可熄灭LED灯,至此简单的按键控制LED灯应用程序开发完成。

  • 可能出现的问题解决方案

    • 执行adb push test /opt时出现/usr/bin/ld: cannot open output file test: Permission denied的解决方法:

      首先使用which adb找到adb包的目录,我这里是/usr/bin/adb,然后执行sudo chmod a+s /usr/bin/adb即可解决该问题。之后执行adb kill-serveradb start-server命令重启adb服务后即可正常上传文件至开发板上。