Linux裸机开发1——点亮第一个LED

Linux裸机开发1——点亮第一个LED

声明:以下知识与图片全部来自韦东山裸机开发视频

一、NOR启动与NAND启动

1、2440系统结构图

以SC2440为例,以下是2440的系统结构图

程序可以烧录在NOR Flash 与 Nand Flash里面
在这里插入图片描述

2、两种启动方式的特性

在这里插入图片描述

二、汇编操作

1、常用汇编指令

//读内存指令 LDR
ldr r0, =0x100		;伪指令,表示将0x100赋给r0、
ldr r0,[r1]			;读内存指令,假设r1的值为x,读取地址x上的数据,并将该数据赋给r0
//赋值指令 MOV
mov r0, r1;			 ;赋值指令,将r1的值赋值给r0
mov r0, #0x100		 ;赋值指令,将0x100赋给r0
//写内存指令 STR
STR  R0,[R1]		;设R1的值为x,将R0的值取出,放入地址x中
//跳转指令	B

2、汇编点亮LED

功能:
控制LED1的亮灭
LED1 B5

汇编代码:

.text
.global _start

_start:
    /*设置IO口方向*/
    ldr r1, =0x56000010
    ldr r0, =0x00000400
    str r0, [r1]

    /*输出低电平,灯亮*/
    ldr r1, =0x56000014
    ldr r0, =0
    str r0, [r1]   

/*死循环*/
halt:
    b halt

三、C语言操作

1、C语言——指针的深度解析

指针变量保存的是地址,即他是一个用于存储地址的变量

int *p = 0x100;		//表示创建一个指针变量p,p的数据类型为(int *),他保存了0x100(这是一个地址)
*p = 0x01;			//*表示解引用,表示将p保存的地址存入0x01
int a = 123			//a是一个普通变量,他存入的值为123
int *pa = &a;		//表示创建一个指针变量pa,他所保存的值为a的地址,符号&为取地址符,表示取地址

2、C语言点亮LED灯

1)简单分析启动过程

一、第一大步

nand 启动将nand flash的前4k地址复制到SRAM中

nor 启动则直接在nor flash中运行,不进行代码的复制

二、第二大步

1、sp(栈指针)指向内存——用于为程序运行时变量的保存分配内存

sp(栈指针)指向内存的顶部,向下递减,栈用于保存临时变量,代码在内存中从0开始,确保不会覆盖掉代码。

2、使用R0-R3传参,跳转到所要执行的函数地址

3、寄存器(pc,lp,sp)将值写入内存中保存起来,栈指针下移

4、使用R0-R3传参(在栈中进行操作),完成函数内部的变量赋值与调用

5、函数执行完毕,恢复寄存器的值(pc,lp,sp),sp恢复原来的值,跳转到lp(返回地址),按照小字节序。

2)编写汇编启动代码

功能:启动文件,分配内存,并且完成main函数的执行

.text
.global _start

_start:
    /*设置内存,:sp 栈*/
    ldr sp, = 4096  /*nand启动*/
    //ldr sp, = 4096+0x400,0000     //nor启动

    /*调用main函数,跳转到main*/
    bl main

/*死循环*/
halt:
    b halt
    
3)编写C语言代码

功能:设置2440的相应寄存器

int main()
{
    //定义方向寄存器以及数据寄存器的地址
    unsigned int *GPDCON = (unsigned int *)0x56000010;
    unsigned int *GPDDAT = (unsigned int *)0x56000014;

    //写入寄存器B5
    *GPDCON = 0x400;
    *GPDDAT = 0;

    return 0;
}

四、改进的汇编代码

1)加入延时功能

功能:加入延时,使 r0 进行传参

.text
.global _start

_start:
    /*设置内存,:sp 栈*/
    ldr sp, = 4096  /*nand启动*/
    //ldr sp, = 4096+0x400,0000     //nor启动

    /*调用延时函数*/
    //将要传递的参数放入r0寄存器中
    mov r0, #0x4000
    //跳转的delay函数
    bl delay

    /*调用main函数*/
    //传参,点亮灯一
    mov r0, #0x01
    //跳转到main
    bl led_delay

    //传参,点亮灯二
    mov r0, #0x02
    //跳转到main
    bl led_delay

/*死循环*/
halt:
    b halt
    
2)加入辨别Nor启动与Nand启动的功能与看门狗功能
.text
.global _start

_start:

    //关闭看门狗
    mov r0, #0x53000000
    mov r1, #0
    str r1, [r0]

    //根据nand与nor的特性自动辨认nor启动与nand启动
    //nor flash可读不可写
    mov r1, #0x0    //r1 = 0 
    ldr r0, [r1]    //将0地址的数值保存在r0中
    str r1, [r1]    //向0地址中写入0
    ldr r2, [r1]    //取出0地址的值
    cmp r1, r2      //比较r1与r2的值,相等则为nand,否则为nor
    ldr sp, = 4096+0x4000000
    moveq sp, #4096   //r1 = r2,nand启动
    streq r0, [r1]    //恢复0地址原来的值

    /*调用main函数,跳转到main*/
    bl main

/*死循环*/
halt:
    b halt
    
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值