rock5b arm64 尝试第一次裸板程序

在linux虚拟机里安装arm64交叉编译环境

apt install gcc make binutils gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu flex bison

写一个helloworld.c

aarch64-linux-gnu-gcc -o helloworld helloworld.c

file helloworld

 cp to /tftp and download to uboot

setenv serverip 192.168.1.9

 setenv ipaddr 192.168.1.20

失败!裸板程序当然不是这样写的啦。。。。。。

模仿别人写个汇编试一下:

 pin 6,8,10已经作为UART和电脑连接使用了,尝试操作pin12 就是GPIO3_B5 109号,就是32*3+13,就是gpiochip3的第13号,从0开始就是在12位

让其输出一个高电平,和pin9GND之间接一个LED灯,来看能不能点亮

看手册 

 GPIO3 base addr 是      0xFEC40000

 第13号应该是low,那么

GPIO_SWPORT_DDR_L
Address: Operational Base + offset (0x0008) 

这个是控制GPIO方向的,先把高16位写1 ,write access enable,就是bit28

bit12写b1,设为 output;

操作了 data direction register,操作  Port Data Register (Low) 

GPIO_SWPORT_DR_L
Address: Operational Base + offset (0x0000)

这个高16位控制write access ,0 是disable,1是enable,那么bit28 写1; 低16位 写0输出低电平,1输出 high

根据我的一个电子书   Modern Arm Assembly Language Programming Covers Armv8-A 32-bit, 64-bit and SIMD.pdf

sub 减法;ret 返回;cmp 比较;

lsl  logical shift left 逻辑左移;asl   arithmetic shift 算数左移;ror rotate right向右旋转,逻辑右移左边补零,这个ror相当于右移并把右移丢失的位补到左边,像环形链表

这个图展示了a数据经过4种不同操作后值的变化。

and 按位与 ;orr 按位或;eor 按位异或;

这个图展示a和b按位操作后的结果

 sdiv signed divide 有符号除法;umull (unsigned multiply long) ;

sxth x1,w1 (sign-extend halfword), sign-extends the halfword value in the low-order 16 bits of register W1 to 64 bits and saves the result in register X1;
sxtb x4,w4 (sign-extend byte) instruction sign-extends the low-order 8 bits of register W4 (argument value e) to 64 bits and saves the result in X4;
madd x10,x11,x1,x10 (multiply-add) 多个相加;存于x10
.equ ARG_J,8   这个.equ可能 等同于c语言的 #define ARG_J 8 ;
.global makes the symbol visible to ld. If you define symbol in your partial program, its value is made available to other partial programs that are linked with it;

b.ge  <label>   jump if >=;   汇编里冒号:前面的都叫标签;通过这些 比较 条件跳转 就可以实现循环了;

b.gt  jump if >;
b.le jump if <=;

b.lt   jump if   <  ;

b.eq jump if == ;  b.eq DoneB   // jump if n == 0
b.ne  not equ?

bl 跳转;bl SumSquaresA_   // call SumSquaresA_;

neg 求相反数

-------------------学了些命令了,来写代码吧--------------------

mkdir gpio109 && cd gpio109

vi gpio109.S

//gpio3方向109,方向寄存器地址  0xFEC40000 + 0x00000008

.global _start

_start:

  mov x0,0xFEC40008  //把GPIO109的方向寄存器地址存入x0

ldr x1,[x0]  //把方向寄存器值取出来

我的.S

Makefile

用uboot tftp后 go,好像能正常运行,但是没有电灯成功

mov 接受的立即数 只能是一个16位的数 或者一个16位数左移16位或32位或48位的数;

aarch64-linux-gnu-objdump -D gpio109.elf >gpio109.dis  看反汇编

---------改---------

 --------还是能运行但是不能点亮-------

-----发现错误:

GPIO109 也是从0开始的。。。。gpio3B5表示   3*32+8+5  !!!!!所以上面代码的x1 = 0x20000000, x2=0x2000;同时由于这些寄存器都是32位的word,所以所有x寄存器改为w;

按位写1也不是and! and的话基本全部写0了,除了我1的那个位还要看别人是1才能得到结果1;所以and全部改为 orr;

还得设置IOMUX;

x改为w后编译报错,还是改回x吧

gpio109.S:8: Error: 64-bit integer or SP register expected at operand 2 -- `ldr w3,[w0]'

gpio109.S:10: Error: 64-bit integer or SP register expected at operand 2 -- `str w3,[w0]'

gpio109.S:12: Error: 64-bit integer or SP register expected at operand 2 -- `ldr w3,[w0]'

gpio109.S:14: Error: 64-bit integer or SP register expected at operand 2 -- `str w3,[w0]'

gpio109.S:18: Error: 64-bit integer or SP register expected at operand 2 -- `ldr w3,[w0]'

gpio109.S:20: Error: 64-bit integer or SP register expected at operand 2 -- `str w3,[w0]'

gpio109.S:22: Error: 64-bit integer or SP register expected at operand 2 -- `ldr w3,[w0]'

gpio109.S:24: Error: 64-bit integer or SP register expected at operand 2 -- `str w3,[w0]'

现在是:

---------------设置io mux---------------

 

 

 

BUS_IOC base address  :  0xFD5F8000 

 设置了iomux还是不行,但是iomux 的 reset就是0000,也就是默认为GPIO功能啊;

凸(艹皿艹 ),算了

看了一本arm64汇编的指导书,学了很多。。。。。

Programming with 64-Bit ARM Assembly Language Single Board Computer Development for Raspberry Pi and Mobile Devices Stephen Smith

电驴上下载的。

最终我的代码:

 当然,还是不行。。

 

 

 

 

 

posted @ 2023-08-03 08:43  杨大茄子  阅读(190)  评论(0编辑  收藏  举报