arm ds软件作为arm公司发布的ADS、DS5软件的延续,具备前两款软件的所有功能。同时将Keil MDK单片机开发软件的功能直接整合到了arm ds软件中。现在arm ds就相当于DS5+MDK两款软件的集合体。优点:能够快速开发Cortex-M单片机程序,同时具备开发高端Cortex-A/R系列芯片的能力。
工程实例代码:
链接:https://pan.baidu.com/s/1a_38k0xU68fnty9bCAR2WQ
提取码:ffu6
Exynos4412数据手册:
链接:https://pan.baidu.com/s/1VHKWuJn2alcLvfJXBGikfg
提取码:8719
开发软件:arm ds软件2018版windows版
程序功能:纯汇编编写的流水灯
arm ds软件下载:
链接:https://pan.baidu.com/s/1Ww5mWiN9sWObYptJesC7Xw
提取码:jcmu
SecureCRT软件下载:
链接:https://pan.baidu.com/s/1mdaKWbLfapHFnekT1_wGjg
提取码:dk2r
点击File >> New >> Project
编译器选择Arm Compiler 5,如果你开发的芯片为arm 64位的。请选择arm compiler 6
点击Finish完成工程创建。
添加汇编文件
选中刚才新建的工程,右键 >> New >> Source File。向工程中添加ledBlink-asm.S汇编文件
点击Finish,这时可以看到工程中已经出现了刚才新建的汇编文件
硬件信息获取
1. 查看开发板上LED对应的端口
打开开发板底板的电路原理图,搜索找到LED记录它的网络标号
然后根据网络标号搜索找到主板上处理器对应端口号
所以这两个LED灯对应的端口就是:GPL2_0、GPK1_1
查阅芯片Exynos4412用户手册
打到GPIO章节的GPK1相关寄存器,这里只需要两个寄存器(控制寄存器、数据寄存器),这里需要用到它们的地址和它们具体位描述。代码编写需要参考这些
编写汇编代码
;说明:LED闪烁汇编裸机程序
;作者:Jack.Tang
;时间:2020年5月22日21:15:13
PRESERVE8 ;8字节对齐
AREA LedBlink_4412, CODE, READONLY ;声明以下内容为代码
;定义寄存器地址,这个和C语言中的#defing宏定义是一样的功能
GPL2CON EQU 0x11000100
GPK1CON EQU 0x11000060
GPL2DAT EQU 0x11000104
GPK1DAT EQU 0x11000064
ENTRY ;以下为汇编程序入口
EXPORT _start ;注意:汇编文件中的符号(symbol)表示的是地址。这个类似于C语言中的函数名称
_start
;关闭看门狗
LDR r0, =0x10060000
MOV r1, #0
STR r1, [r0]
;设置GPL2_0为输出模式--GPL2CON寄存器--LED2
LDR r0, =GPL2CON
LDR r1, =0x00000001
STR r1, [r0]
;设置GPK1_1为输出模式--GPK1CON寄存器--LED3
LDR r0, =GPK1CON
LDR r1, =0x00000010
STR r1, [r0] ;将寄存器r1中的值写回到r0寄存器保存的值对应的地址中。这个就和C语言中的指针*p一样的效果
_loop
;设置GPL2DAT寄存器为1,点亮LED2
LDR r0, =GPL2DAT
MOV r1, #1
STR r1, [r0]
;设置GPK1DAT寄存器为1,熄灭LED3
LDR r0, =GPK1DAT
MOV r1, #0
STR r1, [r0]
;延时
BL Delay
;设置GPL2DAT寄存器为1,熄灭LED2
LDR r0, =GPL2DAT
MOV r1, #0
STR r1, [r0]
;设置GPK1DAT寄存器为1,点亮LED3
LDR r0, =GPK1DAT
MOV r1, #2
STR r1, [r0]
;延时
BL Delay
BL _loop ;无限循环
Delay
;延时“函数名”/入口
LDR r2, =0x2000000 ;设置变量
MOV r3, #0 ;
delay_loop
;延时循环体
SUB r2, r2,#1 ;相当于C语言的自减
CMP r2, r3 ;是否到0,这个会影响到CPSR寄存器中的Z位。相等时Z为1
BNE delay_loop
MOV pc,lr ;返回到函数调用处
END ;程序结束标志
代码解释:
PRESERVE8、AREA LedBlink_4412, CODE, READONLY这两句可以说是在arm ds汇编文件中固定格式。想要详细了解PRESERVE8、AREA指令的朋友可以查阅arm ds软件的帮助文档armasm guild章节。
ENTRY:是arm ds汇编中表示的程序入口说明指令,它常常和EXPORT联合使用即声明某个符号为整个镜像程序的入口地址。比如:这里汇编代码声明了_start为程序入口。注意:汇编中的符号和C语言中的函数名类似,具有地址属性。
EXPORT:声明符号为全局性,即整个工程范围内可见。常常与ENTRY结合使用。然后在工程属性设置窗口中的Image entry处添加此符号(程序入口地址)。
剩余代码请查看注释,注释已经写的足够详细了。对于对arm汇编程序不了解的朋友,建议先去学习下arm汇编语言语法知识。可以去各大IT线上平台学习下。
个人建议:熟悉下主要的几个arm汇编指令即可,学会仿写arm汇编程序即可。其实汇编中用的指令也就几个而已。
添加分散加载文件——scatter文件
选中工程右键 >> New >> Other >> scatter File
在编写scatter文件内容之前,需要查看芯片对应的memory分布
因为开发板已经加载运行了uboot,所以我们现在可以使用DRAM空间(3G)。具体详细的scatter文件语法等请百度或者查看arm ds的帮助文档scatter章节
;Exynos4412芯片内存分布——分散加载文件
;加载域5OK大小用于保存代码
LOAD_REGION 0x40008000 0xC800
{
CODE_REGION 0x40008000 0xC800
{
*(+RO) ;代码执行的区域
}
;这里由于在汇编程序中没有声明变量,所以这段代码是没有用的
;可以注释
VARIABLE_REGION 0x40014800 0x400 ;1K大小的变量区域
{
*(+RW,+ZI)
}
}
这里我直接将代码与变量全部放在了前1.5G的DRAM空间中
注意:一个scatter文件中必须至少有一个固定域。这个固定域用于保存镜像的初始入口。任何一个映像文件都需要指定一个初始入口点(initial entry point),它是影响文件运行时的入口点
加载域:代码存放的地址。就是编译之后得到的二进制文件烧写到rom中的这一段区域,所有的代码RO、预定义变量RW、堆栈之类清不清空无关紧要的大片内存区域ZI,都包括在其中
执行域:代码中变量数据存放的地址。就是把加载域进行‘解压缩’后的样子。比如:RO没有变动还是在ROM中,RW被移到了SRAM中,而ZI被放置在SDRAM中
固定域:所谓固定域是指该域的加载时地址和运行时地址是相同的,程序入口地址就存在于固定域中。
scatter文件格式,就是
加载域
{
执行域1
{
}
执行域2
{
}
}
上述代码分析:
LOAD_REGION 0x40008000 0xC800:设置了加载域地址为0x40008000 ,这个地址可以从4412手册memory map章节查看到。0xC800为这个加载域的大小。LOAD_REGION是这个加载域的名称可以随便取。
注意:加载域与执行域没有包含关系,不要被代码格式所欺骗。想当然的认为和C语言中”{}“一样
设置工程
选中工程右键 >> Properties >> C/C++ Build >> Settings >> Tool Settings >> Arm Linker5 >> Image Layout
添加scatter文件路径、Image镜像入口地址
编译工程
选中工程右键 >> Build Project
选中工程右键 >> Properties >> C/C++ Build >> Settings >> Build Steps
再次编译即可生成bin文件。
可以使用SecureCRT下载bin文件到开发板中。具体操作流程请查看我的另一篇博客:https://blog.csdn.net/twx11213030422/article/details/106241739
选中工程右键 》》 Debug As 选择对应的芯片
注意:如果在芯片列表中没有找到对应芯片需要自行创建芯片数据库。请参考下一章节
这里选择Exynos 44XX >> Bare Metal Debug >> Debug Cortex-A9_0。表示在芯片的第一个A9内核上调试。
点击Browse选择DSTREAM调试器
在File标签中,选择编译生成的axf文件
在Debugger标签中选择Debug from symbo main
最后点击Debug,等待DSTREAM连接上目标设备。连接成功后软件自动会停止在main函数处
LED流水灯.mp4