armv8-a裸机

板子信息

用的orangepi3 lts开发板,资料是真不多。只能自己撸手册,能用的工具也是有限。主芯片SOC用的Allwinner H6, A53的内核,armv8-a64位指令集。

步骤

  • 装编译器
  • 看原理图
  • 看数据手册
  • 找可用项目移植
  • 装linux
  • 传输程序到开发板mmc硬盘或SD卡
  • 用u-boot跑裸机程序

装编译器

不同版本指令集需要使用不同版本编译器,这也是嵌入式开发最烦的地方,除了这
个还有不同公司,不同选项编译器。足够让人头大。最开始我使用arm-none-eabi工具链编译出来,放板子上语法错误。后面发现需要用aarch64-linux-gnu工具链。在电脑上的Ubuntu或者Window的Ubuntu的子系统中安装编译器。

sudo apt install gcc-aarch64-linux-gnu

查看数据手册

看到板子上有两个led,分别是PWR-LED和STATUS-LED,分别对应PL4和PL7引脚。高
电平时LED点亮,低电平熄灭。

查看数据手册

查看数据手册主要是为了确定GPIO相关寄存器地址,Allwinner_H6_V200_User_Manual_V1.1.pdf用户手册的379页给出了GPIO的相关寄存器地址和配置信息。对于PL相关的在434页。对于点灯主要就用到以下3个:

  • GPIOL configure registers(0x07022000) 配置寄存器
  • GPIOL pull registers(0x0702201C) 上拉,下拉
  • GPIOL date registers(0x07022010) 输入,输出数据

我根据手册写了一个头文件,定义了各GPIO寄存器

#ifndef _H6_GPIO_H
#define _H6_GPIO_H#define register(address) (*(volatile unsigned int *)address)#define GPIO_BASE 0x0300B000
#define GPIOS_BASE 0x07022000 #define GPIOC_CFG0 (GPIO_BASE + 2 * 0x0024 + 0x00)
#define GPIOC_CFG1 (GPIO_BASE + 2 * 0x0024 + 0x04)
#define GPIOC_CFG2 (GPIO_BASE + 2 * 0x0024 + 0x08)
#define GPIOC_CFG3 (GPIO_BASE + 2 * 0x0024 + 0x0C)
#define GPIOC_DAT  (GPIO_BASE + 2 * 0x0024 + 0x10)
#define GPIOC_DRV0  (GPIO_BASE + 2 * 0x0024 + 0x14)
#define GPIOC_DRV1  (GPIO_BASE + 2 * 0x0024 + 0x18)
#define GPIOC_PUL0  (GPIO_BASE + 2 * 0x0024 + 0x1c)
#define GPIOC_PUL1  (GPIO_BASE + 2 * 0x0024 + 0x20)
#define GPIOC_INT_CFG0 (GPIO_BASE + 0x200+2*0x20+0x00)
#define GPIOC_INT_CFG1 (GPIO_BASE + 0x200+2*0x20+0x04)
#define GPIOC_INT_CFG2 (GPIO_BASE + 0x200+2*0x20+0x08)
#define GPIOC_INT_CFG3 (GPIO_BASE + 0x200+2*0x20+0x0c)
#define GPIOC_INT_CTL (GPIO_BASE + 0x200+2*0x20+0x10)
#define GPIOC_INT_STA (GPIO_BASE + 0x200+2*0x20+0x14)
#define GPIOC_INT_DEB (GPIO_BASE + 0x200+2*0x20+0x18)#define GPIOD_CFG0 (GPIO_BASE + 3 * 0x0024 + 0x00)
#define GPIOD_CFG1 (GPIO_BASE + 3 * 0x0024 + 0x04)
#define GPIOD_CFG2 (GPIO_BASE + 3 * 0x0024 + 0x08)
#define GPIOD_CFG3 (GPIO_BASE + 3 * 0x0024 + 0x0C)
#define GPIOD_DAT  (GPIO_BASE + 3 * 0x0024 + 0x10)
#define GPIOD_DRV0  (GPIO_BASE + 3 * 0x0024 + 0x14)
#define GPIOD_DRV1  (GPIO_BASE + 3 * 0x0024 + 0x18)
#define GPIOD_PUL0  (GPIO_BASE + 3 * 0x0024 + 0x1c)
#define GPIOD_PUL1  (GPIO_BASE + 3 * 0x0024 + 0x20)
#define GPIOD_INT_CFG0 (GPIO_BASE + 0x200+3*0x20+0x00)
#define GPIOD_INT_CFG1 (GPIO_BASE + 0x200+3*0x20+0x04)
#define GPIOD_INT_CFG2 (GPIO_BASE + 0x200+3*0x20+0x08)
#define GPIOD_INT_CFG3 (GPIO_BASE + 0x200+3*0x20+0x0c)
#define GPIOD_INT_CTL (GPIO_BASE + 0x200+3*0x20+0x10)
#define GPIOD_INT_STA (GPIO_BASE + 0x200+3*0x20+0x14)
#define GPIOD_INT_DEB (GPIO_BASE + 0x200+3*0x20+0x18)#define GPIOF_CFG0 (GPIO_BASE + 5 * 0x0024 + 0x00)
#define GPIOF_CFG1 (GPIO_BASE + 5 * 0x0024 + 0x04)
#define GPIOF_CFG2 (GPIO_BASE + 5 * 0x0024 + 0x08)
#define GPIOF_CFG3 (GPIO_BASE + 5 * 0x0024 + 0x0C)
#define GPIOF_DAT  (GPIO_BASE + 5 * 0x0024 + 0x10)
#define GPIOF_DRV0  (GPIO_BASE + 5 * 0x0024 + 0x14)
#define GPIOF_DRV1  (GPIO_BASE + 5 * 0x0024 + 0x18)
#define GPIOF_PUL0  (GPIO_BASE + 5 * 0x0024 + 0x1c)
#define GPIOF_PUL1  (GPIO_BASE + 5 * 0x0024 + 0x20)
#define GPIOF_INT_CFG0 (GPIO_BASE + 0x200+5*0x20+0x00)
#define GPIOF_INT_CFG1 (GPIO_BASE + 0x200+5*0x20+0x04)
#define GPIOF_INT_CFG2 (GPIO_BASE + 0x200+5*0x20+0x08)
#define GPIOF_INT_CFG3 (GPIO_BASE + 0x200+5*0x20+0x0c)#define GPIOF_INT_CTL (GPIO_BASE + 0x200+5*0x20+0x10)
#define GPIOF_INT_STA (GPIO_BASE + 0x200+5*0x20+0x14)
#define GPIOF_INT_DEB (GPIO_BASE + 0x200+5*0x20+0x18)#define GPIOG_CFG0 (GPIO_BASE + 6 * 0x0024 + 0x00)
#define GPIOG_CFG1 (GPIO_BASE + 6 * 0x0024 + 0x04)
#define GPIOG_CFG2 (GPIO_BASE + 6 * 0x0024 + 0x08)
#define GPIOG_CFG3 (GPIO_BASE + 6 * 0x0024 + 0x0C)
#define GPIOG_DAT  (GPIO_BASE + 6 * 0x0024 + 0x10)
#define GPIOG_DRV0  (GPIO_BASE + 6 * 0x0024 + 0x14)
#define GPIOG_DRV1  (GPIO_BASE + 6 * 0x0024 + 0x18)
#define GPIOG_PUL0  (GPIO_BASE + 6 * 0x0024 + 0x1c)
#define GPIOG_PUL1  (GPIO_BASE + 6 * 0x0024 + 0x20)
#define GPIOG_INT_CFG0 (GPIO_BASE + 0x200+6*0x20+0x00)
#define GPIOG_INT_CFG1 (GPIO_BASE + 0x200+6*0x20+0x04)
#define GPIOG_INT_CFG2 (GPIO_BASE + 0x200+6*0x20+0x08)
#define GPIOG_INT_CFG3 (GPIO_BASE + 0x200+6*0x20+0x0c)
#define GPIOG_INT_CTL (GPIO_BASE + 0x200+6*0x20+0x10)
#define GPIOG_INT_STA (GPIO_BASE + 0x200+6*0x20+0x14)
#define GPIOG_INT_DEB (GPIO_BASE + 0x200+6*0x20+0x18)#define GPIOH_CFG0 (GPIO_BASE + 7 * 0x0024 + 0x00)
#define GPIOH_CFG1 (GPIO_BASE + 7 * 0x0024 + 0x04)
#define GPIOH_CFG2 (GPIO_BASE + 7 * 0x0024 + 0x08)
#define GPIOH_CFG3 (GPIO_BASE + 7 * 0x0024 + 0x0C)
#define GPIOH_DAT  (GPIO_BASE + 7 * 0x0024 + 0x10)
#define GPIOH_DRV0  (GPIO_BASE + 7 * 0x0024 + 0x14)
#define GPIOH_DRV1  (GPIO_BASE + 7 * 0x0024 + 0x18)
#define GPIOH_PUL0  (GPIO_BASE + 7 * 0x0024 + 0x1c)
#define GPIOH_PUL1  (GPIO_BASE + 7 * 0x0024 + 0x20)
#define GPIOH_INT_CFG0 (GPIO_BASE + 0x200+7*0x20+0x00)
#define GPIOH_INT_CFG1 (GPIO_BASE + 0x200+7*0x20+0x04)
#define GPIOH_INT_CFG2 (GPIO_BASE + 0x200+7*0x20+0x08)
#define GPIOH_INT_CFG3 (GPIO_BASE + 0x200+7*0x20+0x0c)
#define GPIOH_INT_CTL (GPIO_BASE + 0x200+7*0x20+0x10)
#define GPIOH_INT_STA (GPIO_BASE + 0x200+7*0x20+0x14)
#define GPIOH_INT_DEB (GPIO_BASE + 0x200+7*0x20+0x18)#define GPIOL_CFG0 (GPIOS_BASE + 0 * 0x0024 + 0x00)
#define GPIOL_CFG1 (GPIOS_BASE + 0 * 0x0024 + 0x04)
#define GPIOL_CFG2 (GPIOS_BASE + 0 * 0x0024 + 0x08)
#define GPIOL_CFG3 (GPIOS_BASE + 0 * 0x0024 + 0x0C)
#define GPIOL_DAT  (GPIOS_BASE + 0 * 0x0024 + 0x10)
#define GPIOL_DRV0  (GPIOS_BASE + 0 * 0x0024 + 0x14)
#define GPIOL_DRV1  (GPIOS_BASE + 0 * 0x0024 + 0x18)
#define GPIOL_PUL0  (GPIOS_BASE + 0 * 0x0024 + 0x1c)
#define GPIOL_PUL1  (GPIOS_BASE + 0 * 0x0024 + 0x20)
#define GPIOL_INT_CFG0 (GPIOS_BASE + 0x200+0*0x20+0x00)
#define GPIOL_INT_CFG1 (GPIOS_BASE + 0x200+0*0x20+0x04)
#define GPIOL_INT_CFG2 (GPIOS_BASE + 0x200+0*0x20+0x08)
#define GPIOL_INT_CFG3 (GPIOS_BASE + 0x200+0*0x20+0x0c)
#define GPIOL_INT_CTL (GPIOS_BASE + 0x200+0*0x20+0x10)
#define GPIOL_INT_STA (GPIOS_BASE + 0x200+0*0x20+0x14)
#define GPIOL_INT_DEB (GPIOS_BASE + 0x200+0*0x20+0x18)#define GPIOM_CFG0 (GPIOS_BASE + 1 * 0x0024 + 1x00)
#define GPIOM_CFG1 (GPIOS_BASE + 1 * 0x0024 + 1x04)
#define GPIOM_CFG2 (GPIOS_BASE + 1 * 0x0024 + 1x08)
#define GPIOM_CFG3 (GPIOS_BASE + 1 * 0x0024 + 1x0C)
#define GPIOM_DAT  (GPIOS_BASE + 1 * 0x0024 + 1x10)
#define GPIOM_DRV0  (GPIOS_BASE + 1 * 0x0024 + 1x14)
#define GPIOM_DRV1  (GPIOS_BASE + 1 * 0x0024 + 1x18)
#define GPIOM_PUL0  (GPIOS_BASE + 1 * 0x0024 + 1x1c)
#define GPIOM_PUL1  (GPIOS_BASE + 1 * 0x0024 + 1x20)
#define GPIOM_INT_CFG0 (GPIOS_BASE + 1x200+1*0x20+0x00)
#define GPIOM_INT_CFG1 (GPIOS_BASE + 1x200+1*0x20+0x04)
#define GPIOM_INT_CFG2 (GPIOS_BASE + 1x200+1*0x20+0x08)
#define GPIOM_INT_CFG3 (GPIOS_BASE + 1x200+1*0x20+0x0c)#define GPIOM_INT_CTL (GPIOS_BASE + 1x200+1*0x20+0x10)
#define GPIOM_INT_STA (GPIOS_BASE + 1x200+1*0x20+0x14)
#define GPIOM_INT_DEB (GPIOS_BASE + 1x200+1*0x20+0x18)// Mode Type
// 此处根据使用习惯对值进行取反操作,因为原始默认值为0x77777777
#define MODE_INPUT  0xf
#define MODE_OUTPUT 0xe// Muli Driving
#define MULI_DRV_0  0x0
#define MULI_DRV_1  0x1
#define MULI_DRV_2  0x2
#define MULI_DRV_3  0x3//Pull Down or Pull Up
#define PULL_DIS  0x0
#define PULL_DOWN 0x1
#define PULL_UP   0x2#endif

找可用项目移植

也是花了好长一段时间才找到这个简单项目,好更改的项目,可以在此项目上自己添加
功能。

git clone https://gitee.com/dawendiguo/arm64-baremetal-demo.git

将aarch和script目录复制到目前目录,更改baremetal.ld和Makefile

# baremetal.ld
# 就改了下启动开始地址,改成了0x40008000,不改应该也可以
ENTRY(_Reset)
SECTIONS
{. = 0x40008000;.startup . : { head.o(.text) }.text : { *(.text) }.data : { *(.data) }.bss : { *(.bss COMMON) }. = ALIGN(8);. = . + 0x1000; /* 4kB of stack memory */stack_top = .;
}

Makefile

# head.s和baremetal.ld位置改了,usart相关代码删除了
ifeq ($(strip $(V)),)E = @echoQ = @
elseE = @\#Q =
endif
export E QCROSS_PREFIX=aarch64-linux-gnu-
CFLAGS += -I includeall: work.binmain.o: main.c gpio.h$(E) "  CC      " $@$(Q) $(CROSS_PREFIX)gcc $(CFLAGS) -c $< -o $@$(Q) $(CROSS_PREFIX)as -c $< -o $@work.elf: main.o head.o$(E) "  LINK    " $@$(Q) $(CROSS_PREFIX)ld -Tbaremetal.ld $^ -o $@work.bin: work.elf$(E) "  OBJCOPY " $@$(Q) $(CROSS_PREFIX)objcopy -O binary $< $@clean:$(E) "  CLEAN   "$(Q) rm -f  work.* *.o

最后再撸一个主函数main.c

/** Allwinner H6 芯片控制GPIOD15,GPIO16信号反转*/
#include "gpio.h"
void delay(int sec);int main(){// 设置gpiol4,gpiol7为输出模式register(GPIOL_CFG0) &= ~(MODE_OUTPUT << (4 * 4));register(GPIOL_CFG0) &= ~(MODE_OUTPUT << (4 * 7));// 都设置为上拉register(GPIOL_PUL0) |= PULL_UP << (2 * 4);register(GPIOL_PUL0) |= PULL_UP << (2 * 7);while(1){/*// 开GPIOL4,关GPIOL7*/register(GPIOL_DAT) |= (1 << 4);register(GPIOL_DAT) &= ~(1 << 7);delay(10000);/*// 关GPIOL4,开GPIOL7*/register(GPIOL_DAT) |= (1 << 7);register(GPIOL_DAT) &= ~(1 << 4);delay(10000);}
}void delay(int sec){for(int i = 0; i < sec; i++){for(int j = 0; j < 10000; j++);}
}

装linux

OrangePi_3_LTS_H6_用户手册_v2.0.pdf17页开始的方法将ubuntu烧写到emmc。顺便配置了一个sshd服务程序。

传输程序到开发板mmc硬盘或SD卡

其实最方便的是u-boot支持网络可以直接使用tftp传递程序文件,但不知道是什么原因我的u-boot没有网络,linux网络还没问题就是u-boot没网。只能用SD卡或直接传输到内部emmc。

# ssh 传输
scp user@host:path/filename  /
# SD卡保存,SD卡使用ext4或fat格式
mv main.bin SD卡根目录

u-boot启动

这里需要一个电脑USB转串口的工具,淘宝买一个20元以内。将GND,RX,TX3个引脚>插入开发板的J3调试口。

# 电脑上安装picocom
sudo apt install picocom
# 开启uart,没有权限用root用户
picocom -b 115200 /dev/ttyUSB0
# 开发板上电,如果没有显示开机u-boot信息交换RX,TX引脚,GND一定要插
# 上电开机进去u-boot到快进系统时会提示按空格进u-boot命令行,不行就多试几
次

(u-boot命令行)[],这里有简单u-boot命令行使用介绍,我们这里只用到几个命令>。

# 选择内部mmc或者SD卡
mmc list
# 根据自己实际选择硬盘,我的0是SD卡,1是内部mmc硬盘
mmc dev 0 或者 1
# 可以使用fatls或者ext4ls查看一下文件内容,有多个分区可以使用mmc 1:1 这种格式,1:1表示第1号硬盘第一个分区
ext4ls mmc 1:1
# 载入程序到内存,40008000是前面写程序时baremetal.ld中指定的起始地址
ext4load mmc 1:1 40008000 work.bin
# 运行程序
go 40008000
# 如果程序运行成功,应该就可以看到板子上的电源指示灯和状态指示灯,一红一黄交替闪烁了,
# 如果程序运行后开发板重启,有可能就是程序或者编译器有问题了。

至此算是完成了裸机跑soc芯片GPIO的程序了,接下来就可以进一步玩一下mmu和
Timer了,还有一个复杂的中断GIC。
总结起来相比树莓派,i.MX的板子,全志的资料真的是太有限了。很多项目也是
直接借鉴树莓派,要想自己玩还是比较困难。wiring库也是走的树莓派的老路,就
连实现方法也如出一辙,都是直接使用/dev/mem简单粗暴。不过万事开头难,既然
裸机都通了,linux驱动开发也就不远了。
郁闷的是目前国内的linux教程多是基于2.6版本,目前内核都5.19了变化也是相当
大。就我目前了解。2.6还在玩file_operations结构体,现在gpio都进化到又有其
他中间件了。原来操作arm寄存器直接自己写地址位置,现在又进化成dtb文件了。
真是改变无处不在,相比于目前国内落后的学习资料,不知道又要掉多少坑。
arm教程版本也是滞后的,有的还在讲arm4,arm5指令集。最新的armv9-a都已经出来了。感觉armv8-a的都难找到几个。CSDN上真正在orangepi3 lts上玩裸机的也是基本没看到过。

orangepi3 lts裸机点灯相关推荐

  1. Orange pi GPIO输出控制,裸机点灯大法(二)!

    文章目录 Orange pi GPIO输出控制方式 前言 1.OPi.GPIO安装及使用 2.引脚编号 3.WiringOP-Zero-Python安装及使用 4.WiringOP-Zero 安装及使 ...

  2. Orange pi GPIO输出控制,裸机点灯大法(一)!

    裸机点灯大法 玩树莓派或者香橙派,如果不玩裸机点灯,那岂不是不完整.所谓裸机点灯,即一块裸板,通过gpio输出控制,实现控制板载绿色的电源指示灯以及红色的状态指示灯 裸机点灯(GPIO输出控制)的两种 ...

  3. orangepi3 lts动态加载驱动

    orangepi3 lts驱动编译 源码下载 按照手册指示从github下载或直接从百度网盘下载 git clone https://github.com/orangepi-xunlong/orang ...

  4. 【点灯鼠教程】K210裸机点灯之旅(1)点亮SSD1306【C开发I2C】

    万物基于点灯 --沃兹基硕德 点灯,I2C点灯 就像正常点灯一样,打开勘智IDE,大地球,礼物,find i2c,None... 果断下载GPIO,打开百度! 还是None? 自己动手! API,I2 ...

  5. K210裸机点灯之旅(1)点亮SSD1306【c开发i2c】

    万物基于点灯 --沃兹基硕德 点灯,I2C点灯 就像正常点灯一样,打开勘智IDE,大地球,礼物,find i2c,None... 果断下载GPIO,打开百度! 还是None? 自己动手! API,I2 ...

  6. orangePi3 lts

    最终我还是在21.04版本上编译的(18.04上可以正常编译uboot kernel rootfs以及full image,但是启动后wifi没法正常连接....),这样esp32环境也可用. 到 h ...

  7. 【转】基于Ubuntu 14.04 LTS编译Android4.4.2源代码

    原文网址:http://blog.csdn.net/gobitan/article/details/24367439 基于Ubuntu 14.04 LTS编译Android4.4.2源代码 Denni ...

  8. 一灯大师--关于如何进行裸机开发的学习心得

    今天!是万里长征第一步.在原子哥的资料自学下终于完成了在I.MX6ULL下的第一个裸机点灯.写这个是总结一下点灯的步骤(当然以后所有的裸机开发基本步骤都差不多). 在I.MX6ULL上点灯其实和STM ...

  9. 主线剧情01-ARM-IMX6ULL基础学习记录

    ARM & i.MX6ULL 基础学习记录 编辑整理 by Staok 本文大部分内容摘自"100ask imx6ull"开发板的配套资料(如<IMX6ULL裸机开发 ...

最新文章

  1. Redis进阶实践之三如何在Windows系统上安装安装Redis
  2. 自然语言处理(NLP)之英文单词词性还原
  3. DL之CycleGAN:基于TF利用CycleGAN模型对apple2orange数据集实现图像转换—训练测试过程全记录
  4. linux需要的GLIBCXX版本,GCC版本中没有GLIBCXX_3.4.15解决
  5. kafka mysql安装与配置_Mac环境canal+mysql+kafka的安装及使用
  6. php多分支结构 案例,第4天 PHP分支、循环结构
  7. 搞多媒体开发?吴威麒:先拉个书单看看
  8. 2018,腾讯110,感谢有你
  9. 【clickhouse】clickhouse UTC 时间带有时区 如何写入
  10. multiparty 和 busboy
  11. 博客推广——提交搜索引擎
  12. 【经典】产品人面试中的一些软回答~~
  13. halcon印章文字提取
  14. 09Apache POI学习笔记
  15. oracle系统试算平衡表,oracle数据库中常用的系统表
  16. Linux系统和Windows系统的区别
  17. Spring Cloud升级之路 - Hoxton - 10. 网关重试带Body的请求Body丢失的问题
  18. LVGL 8.0 lv_demo_widgets的学习
  19. ROS1中Gazebo案例都有哪些机器人呢(Noetic2022)
  20. 傅里叶变换、离散傅里叶变换(DFT)、快速傅里叶变换(FFT)详解

热门文章

  1. WiFi-Portal认证中的坑:iOS9.3.1弹出portal慢+认证失败问题
  2. 2018支付宝集五福最新攻略!
  3. Multidex记录三:源码解析
  4. 使用Python制作漫画和小说电子书的方法总结
  5. ApiSix 开启SkyWalking插件,实现链路信息追踪
  6. 基于云存储的个性化地图-李乐
  7. Java并发-JMM内存模型
  8. 当乔丹和科比遇见了Python
  9. 大数据学习 之 Spark 概述
  10. 30.英语单词背诵—源书番外