本帖最后由 kira 于 2023-2-27 12:59 编辑
前言本来这篇文章应该在上周就写完的,不过突然被安排出差,一直忙到了现在,终于可以静下心来做些其它事情。 之前和龙芯3A5000主机一起送过来的还有一块龙芯2K500的迷你开发板,整个板子不到巴掌大小。之前只是简单做了上电启动,这次拿到了比较完整的开发资料,可以尝试为开发板编写一些程序了。 由于暂时没有屏幕,只能先试着做一些其它的事情,如通信和IO控制,其中最简单,最基础的就是LED灯的控制。然后我就发现,这个板子居然有一颗可以调节亮度的LED灯!没错,之前做的LED控制都只能进行开关操作,而可以调节亮度,意味着可以做出更多的显示效果,这次我就做了一个呼吸灯的效果。 然后,我也简单了解了一下这种亮度调节的原理,实际上就是通过调节PWM输出的占空比,改变一个周期内输出的高低电平所占的比例,实现控制LED灯亮度的效果。由于引脚输出的电压是固定的,所以不能通过改变电平来控制亮度,而改变高低电平的占空比则是另一种思路,嵌入式设备的屏幕背光亮度调节也是基于同样的原理。 开发板上电启动、连接串口终端由于暂时没有屏幕,想要和开发板进行交互就只能通过终端的方式,通常开发板都会有调试串口,我们先通过串口终端登录设备,配置好网口IP地址后,再通过网络连接登录设备。 串口的连接方式如下图: 将绿、白、黑三色线以图中方式接好(红线不用接),USB端插入到电脑,应该不需要装驱动,电脑可以直接识别出串口设备。 打开串口终端工具,比如Windows MobaXterm,linux minicom等,我比较喜欢用putty。 配置好端口,设置
波特率:115200
数据位:8位
停止位:1位
校验:无
硬件流控:无 然后给开发板接通电源,就可以看到调试输出信息了。 - [root@LS-GD ~]# uname -a
- Linux LS-GD 5.10.0.lsgd-g434b00a6badf #1 PREEMPT Wed Sep 14 12:57:58 CST 2022 loongarch64 GNU/Linux
- [root@LS-GD ~]#
复制代码 配置交叉编译环境2K500开发板是loongarch64架构的嵌入式板卡。下载好对应的交叉编译工具链后,解压到系统/opt/目录下。按手册来就好~ - $ sudo tar -xf toolchain-loongarch64-linux-gnu-gcc8-host-x86_64-2022-07-18.tar.xz -C /opt/
复制代码然后我们需要将交叉编译器添加到系统路径,方便我们接下来使用。 这里我直接将配置写成脚本,方便下次使用。 - $ cd /opt/toolchain-loongarch64-linux-gnu-gcc8-host-x86_64-2022-07-18
- # 创建脚本
- $ sudo touch environment-setup-loongarch64-linux-gnu
- # 添加可执行权限
- $ sudo chmod +x environment-setup-loongarch64-linux-gnu
- # 修改脚本内容
- $ sudo vi environment-setup-loongarch64-linux-gnu
- # 内容如下~
复制代码- # environment-setup-loongarch64-linux-gnu
- CC_PREFIX=/opt/toolchain-loongarch64-linux-gnu-gcc8-host-x86_64-2022-07-18
- export PATH=$CC_PREFIX/bin:$PATH
- export LD_LIBRARY_PATH=$CC_PREFIX/lib:$LD_LIBRARY_PATH
- export LD_LIBRARY_PATH=$CC_PREFIX/loongarch64-linux-gnu/lib64:$LD_LIBRARY_PATH
- export ARCH=loongarch
- export CROSS_COMPILE=loongarch64-linux-gnu-
复制代码接下来测试一下交叉编译环境 - $ cd ~
- $ . /opt/toolchain-loongarch64-linux-gnu-gcc8-host-x86_64-2022-07-18/environment-setup-loongarch64-linux-gnu
- $ loongarch64-linux-gnu-gcc -v
- Using built-in specs.
- COLLECT_GCC=loongarch64-linux-gnu-gcc
- COLLECT_LTO_WRAPPER=/opt/toolchain-loongarch64-linux-gnu-gcc8-host-x86_64-2022-07-18/bin/../libexec/gcc/loongarch64-linux-gnu/8.3.0/lto-wrapper
- Target: loongarch64-linux-gnu
- Configured with: /dev/shm/build_loongarch64_gcc8-host-x86_64_2022-07-18/src/gcc/configure --build=x86_64-redhat-linux --host=x86_64-redhat-linux --target=loongarch64-linux-gnu --program-prefix=loongarch64-linux-gnu- --prefix=/dev/shm/build_loongarch64_gcc8-host-x86_64_2022-07-18/cross --libdir=/dev/shm/build_loongarch64_gcc8-host-x86_64_2022-07-18/cross/lib --with-gxx-include-dir=/dev/shm/build_loongarch64_gcc8-host-x86_64_2022-07-18/cross/sysroot/usr/include/c++ --with-sysroot=/dev/shm/build_loongarch64_gcc8-host-x86_64_2022-07-18/cross/sysroot --with-native-system-header-dir=/usr/include --with-arch=loongarch64 --with-abi=lp64 --with-multilib-list=lp64d,lp64s --with-pkgversion='LoongArch\ GNU\ toolchain\ vec.32-rc2' --disable-linker-build-id --with-newlib --without-headers --disable-shared --enable-threads=posix --enable-tls --enable-languages=c,c++,fortran --enable-__cxa_atexit --enable-libquadmath-support --disable-gcov --disable-libcc1 --enable-initfini-array --disable-nls --disable-bootstrap --with-glibc-version=2.28
- Thread model: posix
- gcc version 8.3.0 (LoongArch GNU toolchain vec.32-rc2)
复制代码可以看到loongarch交叉编译器的版本信息,配置交叉编译环境完成。 编写程序控制LED灯的亮度,Linux系统已经有驱动实现了,我们要做的操作就是向相应的文件中写入数值即可,剩下的都是系统的事情。 对于一般的LED灯,只有开关两个选项,写入0为关闭,写入非0值打开。 而对于PWM控制的LED灯,需要写入具体数值来控制灯的亮度,同样,0为关闭,写入数值越大LED灯就越亮,当然,这是有上限的。这里经过测试,写入255后,LED灯达到最亮。 而这次写的呼吸灯程序,则是逐渐改变LED灯的亮度,实现LED灯缓慢闪烁的效果。
这里我将亮度分为10个级别,从0到255(2^8 - 1),每100ms改变一下LED灯的亮度,一个周期刚好为2秒(从灭到最亮,然后从最亮到灭)。 至于为什么是分为这10个级别,而不是从0~255变化,大家可以自己试试,看一下效果。 以下是完整程序: - /**
- * file: led-pwm.c
- */
- #include <fcntl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- /**
- * @brief 呼吸灯效果
- * @param fd 设备文件
- */
- void breath(int fd);
- int main(int argc, char *argv[])
- {
- if (argc < 2)
- {
- printf("Please input LED device.\n");
- return -1;
- }
- int fd;
- char file[64];
- sprintf(file, "%s/brightness", argv[1]);
- /* 打开设备文件 */
- fd = open(file, O_WRONLY);
- if (fd < 0)
- {
- printf("Error open file: %s\n", file);
- return fd;
- }
- breath(fd);
- /* 关闭设备文件 */
- close(fd);
- return 0;
- }
- void breath(int fd)
- {
- const int values[10] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 255};
- char buf[5];
- while (1)
- {
- /* 从暗到亮 */
- for (int i = 0; i < 10; i++)
- {
- sprintf(buf, "%d", values[i]);
- write(fd, buf, sizeof(buf));
- usleep(100000); // 休眠100ms
- }
- /* 从亮到暗 */
- for (int i = 9; i >= 0; i--)
- {
- sprintf(buf, "%d", values[i]);
- write(fd, buf, sizeof(buf));
- usleep(100000); // 休眠100ms
- }
- }
- }
复制代码然后编译,得到在开发板上运行可执行程序。 - $ loongarch64-linux-gnu-gcc led-pwm.c -o led-pwm
复制代码 下载程序到开发板运行前的最后一步,需要将编译好可执行程序复制到开发板上,我通常是使用scp命令将文件复制到开发板。 需要先在串口终端通过ifconfig设置开发板的网口IP,第一次使用scp前,需要先用ssh登录到开发板。
由于之前不知道默认密码是什么,所以先用passwd命令改了密码。 - # 例:将可执行程序复制到开发板
- $ scp ./led-pwm root@192.168.0.10:~/
- # 使用 ssh 登录开发板
- $ ssh root@192.168.0.10
- # 为程序添加可执行权限(在开发板操作)
- ~ $ chmod +x ./led-pwm
- # 运行程序
- ~ $ ./led-pwm /sys/class/leds/led1-pwm
复制代码 实际运行效果由于开发板的LED2默认是心跳模式[heartbeat],所以会一直一闪一闪的,在运行呼吸灯程序前,可以先把LED2改为[none]模式。 - ~ $ echo none > /sys/class/leds/led2/trigger
复制代码执行编写的呼吸灯程序 - ~ $ ./led-pwm /sys/class/leds/led1-pwm
复制代码实际运行效果如下:
|