官网下载的SDK包中就有交叉工具链,米尔提供的这个 SDK 中除了包含各种源代码外还提供了必要的交叉工具链,可以直接用于编译应用程序等。
用户可以直接使用次交叉编译工具链来建立一个独立的开发环境,可单独编译 Bootloade
r,Kernel 或者编译自己的应用程序。我们这一节重点是编译应用程序。
当然,前提是先安装虚拟机,我们开发环境配置在ubuntu18.04虚拟机下。
官网链接: MYIR
源码暂不提供 ,应该是需要单独申请,没关系,并不影响我们应用程序开发。
建立工具链目录,并解压,完成后:
开发包里写好了env.sh脚本,可以完成环境配置:
- #!/bin/sh
-
- export PATH=$PATH:/home/hy/jd9x/tool/gcc_linaro/gcc-arm-none-eabi-7.3.1/bin:/home/hy/jd9x/tool/gcc_linaro/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-elf/bin:/home/hy/jd9x/tool/gcc_linaro/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin
- export ARCH=arm64
- export CROSS_COMPILE=aarch64-linux-gnu-
- export PREFIX=aarch64-linux-gnu-
- export AS=aarch64-linux-gnu-as
- export LD=aarch64-linux-gnu-ld
- export CC=aarch64-linux-gnu-gcc
- export AR=aarch64-linux-gnu-ar
- export NM=aarch64-linux-gnu-nm
- export STRIP=aarch64-linux-gnu-strip
- export OBJCOPY=aarch64-linux-gnu-objcopy
- export OBJDUMP=aarch64-linux-gnu-objdump
主要也是配置各种路径参数。
- ~/jd9x$ aarch64-linux-gnu-gcc -v
- Using built-in specs.
- COLLECT_GCC=aarch64-linux-gnu-gcc
- COLLECT_LTO_WRAPPER=/home/hy/jd9x/tool/gcc_linaro/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/../libexec/gcc/aarch64-linux-gnu/7.3.1/lto-wrapper
- Target: aarch64-linux-gnu
- Configured with: '/home/tcwg-buildslave/workspace/tcwg-make-release/builder_arch/amd64/label/tcwg-x86_64-build/target/aarch64-linux-gnu/snapshots/gcc.git~linaro-7.3-2018.05/configure' SHELL=/bin/bash --with-mpc=/home/tcwg-buildslave/workspace/tcwg-make-release/builder_arch/amd64/label/tcwg-x86_64-build/target/aarch64-linux-gnu/_build/builds/destdir/x86_64-unknown-linux-gnu --with-mpfr=/home/tcwg-buildslave/workspace/tcwg-make-release/builder_arch/amd64/label/tcwg-x86_64-build/target/aarch64-linux-gnu/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gmp=/home/tcwg-buildslave/workspace/tcwg-make-release/builder_arch/amd64/label/tcwg-x86_64-build/target/aarch64-linux-gnu/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gnu-as --with-gnu-ld --disable-libmudflap --enable-lto --enable-shared --without-included-gettext --enable-nls --with-system-zlib --disable-sjlj-exceptions --enable-gnu-unique-object --enable-linker-build-id --disable-libstdcxx-pch --enable-c99 --enable-clocale=gnu --enable-libstdcxx-debug --enable-long-long --with-cloog=no --with-ppl=no --with-isl=no --disable-multilib --enable-fix-cortex-a53-835769 --enable-fix-cortex-a53-843419 --with-arch=armv8-a --enable-threads=posix --enable-multiarch --enable-libstdcxx-time=yes --enable-gnu-indirect-function --with-build-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/builder_arch/amd64/label/tcwg-x86_64-build/target/aarch64-linux-gnu/_build/sysroots/aarch64-linux-gnu --with-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/builder_arch/amd64/label/tcwg-x86_64-build/target/aarch64-linux-gnu/_build/builds/destdir/x86_64-unknown-linux-gnu/aarch64-linux-gnu/libc --enable-checking=release --disable-bootstrap --enable-languages=c,c++,fortran,lto --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=aarch64-linux-gnu --prefix=/home/tcwg-buildslave/workspace/tcwg-make-release/builder_arch/amd64/label/tcwg-x86_64-build/target/aarch64-linux-gnu/_build/builds/destdir/x86_64-unknown-linux-gnu
- Thread model: posix
- gcc version 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05)
看起来应该没什么问题了。
- TARGET = $(notdir $(CURDIR))
- objs := $(patsubst %c, %o, $(shell ls *.c))
- $(TARGET)_app:$(objs)
- $(CC) -o $@ $^
- %.o:%.c
- $(CC) -c -o $@ $<
- clean:
-
- rm -f $(TARGET)_app *.all *.o
- ${CC} -I . -c helloWorld.
稍稍解释下:
Makefile 有其自身的一套规则。
target ... : prerequisites ...
command
其中:
target 可以是一个 object file(目标文件),也可以是一个执行文件,还可以是一个
标签(label)。
prerequisites 就是要生成那个 target 所需要的文件或是目标。
command 也就是 make 需要执行的命令。
所以,上面的make文件的内容解析:
$(notdir $(path)): 表示把 path 目录去掉路径名,只留当前目录名,比如当
前 Makefile 目录为/home/wujl/key_led,执行为就变为 TARGET = key_led
$(patsubst pattern, replacement,text) :用 replacement 替换 text 中符合
格式"pattern" 的字符,如$(patsubst %c, %o, $(shell ls *.c)),表示先列出
当前目录后缀为.c 的文件,然后换成后缀为.o
CC:C 编译器的名称
CXX: C++编译器的名称
clean: 是一个约定的目标
-
- #include
- #include
- #include
-
- /* print helloworld */
- int main(int argc, char **argv)
- {
-
- printf("j9x, hello world \n");
-
- return 0;
- }
生成可执行的应用程序helloWorld_app
此时,可以用filezilla把上述可执行文件copy到目标机目录下:
转移至secureCRT调试页面,执行刚刚copy过来的可执行文件:
- root@myd-jd9x:~/app# ls
- helloWorld_app
- root@myd-jd9x:~/app# ./helloWorld_app
- -sh: ./helloWorld_app: Permission denied
- root@myd-jd9x:~/app# cd ../
- root@myd-jd9x:~# chmod 777 app -R
- root@myd-jd9x:~# cd app
- root@myd-jd9x:~/app# ./helloWorld_app
- j9x, hello world
- root@myd-jd9x:~/app#
中间遇到读写权限问题,用chmod命令设置下。
4.1 环境测试
linux下,一切皆是文件,外设也是。
操作 LED 的目录为/sys/class/leds
- root@myd-jd9x:~/app# cd /sys/class/leds
- root@myd-jd9x:/sys/class/leds# ls
- debug mmc0:: mmc1:: mmc2:: run
- root@myd-jd9x:/sys/class/leds#
测试debug灯不同状态
读取,熄灭,点亮,触发模式:
- root@myd-jd9x:/sys/class/leds# cat ./debug/brightness
- 0
-
- root@myd-jd9x:/sys/class/leds# echo 0 > ./debug/brightness
- root@myd-jd9x:/sys/class/leds# echo 1 > ./debug/brightness
- root@myd-jd9x:/sys/class/leds# echo timer > ./debug/trigger
- root@myd-jd9x:/sys/class/leds# echo heartbeat > ./debug/trigger
4.2 编写应用程序
功能: 根据输入参数来配置debug按不同模式来工作
off: 关闭
mode0: timer
mode1: heartbeat
代码:
- #include <linux/input.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- /* ./key_led /dev/input/event0 noblock */
- int main(int argc, char **argv)
- {
- int fd,bg_fd;
- int err, len, i;
- unsigned char flag;
- unsigned int data[1];
- char *bg = "/sys/class/leds/debug/trigger";
-
- struct input_event event;
- if(argc>2){
- printf("argv must in 0-2. \n");
- return -1;
- }
- if(!strcmp(argv[1],"mode0")){
- printf("blink mode 0. \n");
- system("echo timer > /sys/class/leds/debug/trigger");
- return 0;
- }
- if(!strcmp(argv[1],"mode1")){
- printf("blink mode 1. \n");
- system("echo heartbeat > /sys/class/leds/debug/trigger");
- return 0;
- }
-
- if(!strcmp(argv[1],"off")){
- printf("blink mode off. \n");
- system("echo 0 > /sys/class/leds/debug/brightness");
- return 0;
- }
- else{
- printf("blink set error. \n");
- }
编译测试:
- root@myd-jd9x:~/app# ./ledBlink_test off
- blink mode off.
- root@myd-jd9x:~/app# ./ledBlink_test mode0
- blink mode 0.
- root@myd-jd9x:~/app# ./ledBlink_test mode1
- blink mode 1.
结果OK。