1. 建立交叉编译链接环境
官网下载的SDK包中就有交叉工具链,米尔提供的这个 SDK 中除了包含各种源代码外还提供了必要的交叉工具链,可以直接用于编译应用程序等。
用户可以直接使用次交叉编译工具链来建立一个独立的开发环境,可单独编译 Bootloade
r,Kernel 或者编译自己的应用程序。我们这一节重点是编译应用程序。
1.1 建立虚拟机环境
当然,前提是先安装虚拟机,我们开发环境配置在ubuntu18.04虚拟机下。
1.2. 下载并安装SDK
官网链接: MYIR
源码暂不提供 ,应该是需要单独申请,没关系,并不影响我们应用程序开发。
建立工具链目录,并解压,完成后:
1.3 环境配置
开发包里写好了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
主要也是配置各种路径参数。
2. 测试下环境安装情况:
~/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)
看起来应该没什么问题了。
3. Hello World小应用,编译下载,运行
3.1 编辑makefile
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: 是一个约定的目标
3.2 编辑应用代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* print helloworld */
int main(int argc, char **argv)
{
printf("j9x, hello world \n");
return 0;
}
3.3 在项目目录下,编译:
生成可执行的应用程序helloWorld_app
3.4 目标机执行
此时,可以用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. 资源调用-配置点灯
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。