专题10-C语言环境初始化

Bootloader的前半部分需要汇编语言的使用,后半部分需要 C语言的使用。

第一课.栈的初始化

一.概念解析

栈是一种具有后进先出性质的数据组织方式,也就是说后存放的先取出,先存放的后取出。栈底是第一个进栈的数据所处的位置,栈顶是最后一个进栈的数据所处的位置。

  1. 根据SP指针指向的位置,栈可以分为满栈和空栈

(1)满栈:当堆栈指针SP总是指向最后压入堆栈的数据

(2)空栈:堆栈指针SP指向下一个将要放入数据的空位置

ARM采用满栈。

  1. 升降栈

根据SP指针的移动方向,栈可以分为升栈和降栈

(1)升栈:随着数据的入栈,SP指针从低地址指向高地址。

(2)降栈:随着数据的入栈,SP指针从高地址指向低地址。

ARM采用降栈

  1. 栈帧

简单的讲,栈帧(stack frame)就是一个函数所使用的的那部分栈,所有函数的栈帧串起来就是一个完整的栈。栈帧的两个边界分别由fp(r11)和sp(r13)来限定。

二. 栈的作用

(1)保存局部变量

#include <stdio.h>

int main()

{

int a;

a++;

return a;

}

(2)参数传递

#include <stdio.h>

void func1(int a,int b,int c,int d,int e,int f)

{

int k;

k=e+f;

}

int main()

{

func1(1,2,3,4,5,6);

return 0;

}

(3)保存寄存器变量

#include <stdio.h>

void func2(int a,int b)

{

int k;

k=a+b;

}

void func1(int a,int b)

{

int c;

func2(3,4);

c=a+b;

}

int main()

{

func1(1,2);

return 0;

}

三.写代码

reset:

bl set_svc

bl disable_watchdog

bl disable_interrupt

bl disable_mmu

bl init_clock

bl init_sdram

bl copy_to_ram

bl init_stack

bl light_led

init_stack:    @2440,内存地址加64Mb

ldr sp, =0x34000000

mov pc ,lr

init_stack:    @6410,内存地址加64Mb

ldr sp, =0x54000000

mov pc ,lr

init_stack:    @210,内存地址加64Mb

ldr sp, =0x24000000

mov pc ,lr

第二课.初始化Bss段

·Bss段的作用

初始化的全局变量存在数据段,局部变量存在栈,malloc申请的数据存在堆,未初始化全局变量存放在bss段。找到bss段的起始地址和结束地址,往其中放的数都是0,在链接器脚本中有bss_start记录起始地址和bss_end终止地址。

bl clean_bss   @2440、6410、210通用

clean_bss:

ldr r0, =bss_start

ldr r1, =bss_end

cmp r0, r1  @若相等的话

moveq pc, lr  @直接返回,什么不做

clean_loop:     @不相等,执行循环语句

mov r2, #0

str r2, [r0], #4

cmp r0, r1

bne clean_loop

mov pc, lr

第三课.一跃进入C大门

这一阶段开始从汇编语言转换成C语言来进行

我们思考的两个问题:

采用什么方式跳转?检验是否跳转成功?

一. 跳转

当前我们的程序运行在垫脚石中,我们希望跳转到内存中的main函数,这种方式是绝对跳转。相对跳转需要两个位置之间的差值,相对跳转的会发现SRAM(垫脚石)之中与内存之中都有main函数,会直接跳转到垫脚石之中的main函数。所以我们采用绝对跳转。

代码:

.global _start

reset:

bl set_svc

bl disable_watchdog

bl disable_interrupt

bl disable_mmu

bl init_clock

bl init_sdram

bl copy_to_ram

bl init_stack

bl clean_bss

ldr pc, =gboot_main

@     bl light_led

在C语言文件中,写下如下的代码:

#define GPBCON (volatile unsigned long*)0x56000010

#define GPBDAT (volatile unsigned long*)0x56000014

int gboot_main()

{

*(GPBCON) = 0x15400;

*(GPBDAT) = 0x6BF;

return 0;

}

Makefile中修改:

all: start.o main.o

arm-linux-ld -Tgboot.lds -o gboot.elf $^

arm-linux-objcopy -O binary gboot.elf gboot.bin

%.o : %.S

arm-linux-gcc -g -c $^

%.o : %.c

arm-linux-gcc -g -c $^

.PHONY: clean

clean:

rm *.o *.elf *.bin

二. 使用C语言点亮led

将汇编语言中的点亮led操作注销了,将这部分代码导入到C文件中。

#define GPBCON (volatile unsigned long*)0x56000010

#define GPBDAT (volatile unsigned long*)0x56000014

int gboot_main()

{

*(GPBCON) = 0x15400; //控制结存器

*(GPBDAT) = 0x6BF;   //数据寄存器

return 0;

}

C语言中的地址都是unsigned long*,为了减少不必要的优化,外加volatile unsigned long,给地址赋值在前面加星号,加入汇编代码的值就好。

注意:

使用210开发板编写的代码,是运行不出来的。在使用210的时候,我们加了16字节的头,这是给bootloader使用的。当把垫脚石中的代码复制到内存的时候,这个头就不需要使用的,需要将这个头文件去掉。210的垫脚石复制从第16个字节开始,其中内存初始化程序是:

         copy_to_ram:

ldr r0, =0xd0020010

ldr r1, =0x20008000

add r3, r0, #1024*4

第四课.第4课-C与汇编混合编程

C语言与汇编的混合编程不仅出现在,我们的bootloader设计中,出现在驱动中,在其他的嵌入式开发中也是需要的。下面我们看一下两种语言各自的优点。

汇编语言:执行效率高;编写繁琐。

C语言:可读性强,移植性好,调试方便。

在一些执行效率需要很高,能更直接地控制处理器的地方,我们必须要使用汇编语言。

  1. 汇编调用C函数

若是下汇编语言下调用C函数,直接在程序中,将函数名给pc指针就好。我们之前写的代码就是汇编调用C函数。

  1. C语言调用汇编

将汇编语言的函数名放在C语言中,单在这之前要把调用的函数升级为全局的。也就是在相应的函数之前加上.global。

  1. C语言内嵌汇编语言

这部分我们不是进行引用,而是直接在C语言中写汇编语言。

(1)格式

_asm_(

汇编语言部分

:输出部分

:输入部分

:破坏描述部分

);

C语言内嵌汇编以关键字“_asm_”或者“asm”开始,下辖四个部分,各部分之间使用“:”分开,第一部分是必须写的,后面的三部分是可以省略的,但是分号:不能省略!

l  汇编语句部分;汇编语句的集合,可以包含多条汇编语句,每条语句之间需要使用换行符“\n”合开或者分号“;”隔开。

l  输出部分:在汇编中被修改的C变量列表。

l  输出部分:作为参数输入到会汇编中的变量列表。

l  破坏描述部分:执行汇编指令会被破坏的寄存器描述

(2)范例

void write_p51_c1 (unsigned long value)

{

_asm_(

“mcr p15, 0, %0, c1, c0, 0\n”   @其中%0表示0号参数

:

:”r”(value)@编译器选择一个R*寄存器  将value的值给%0

:”memory”);

}

Unsigned long read_p15_c1 (void)

{

unsigned long value;

_asm_(

“mcr p15, 0, %0, c1, c0, 0\n”

: ”=r” (value) @ ’=’ 表示只写操作数,用于输出部

: “memry”);
         return value;

}

unsigned long old;

unsigned long temp;

_asm_ volatile(

“mrs  %0,  cpsr  \n”

“orr  %1,  %0,  #128  \n”

“msr  cpsr_c,  %1\n”

: ”=r” (old), “=r” (temp)

:

: “memory”);

使用volatile来告诉编译器,不要对接下来的这部分代码进行优化。

转载于:https://www.cnblogs.com/free-1122/p/11452038.html

第二季-专题10-C语言环境初始化相关推荐

  1. 第二季:9.生产环境服务器变慢,诊断思路和性能评估谈谈?【Java面试题】

    第二季:9.生产环境服务器变慢,诊断思路和性能评估谈谈? [Java面试题] 前言 推荐 9.生产环境服务器变慢,诊断思路和性能评估谈谈? Linux诊断原因 命令集合 整机:top,查看整机系统新能 ...

  2. 第二季5:配置视频捕获模块(step3:VI模块)

    以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除. 前言 本文将详细介绍博文第二季3:sample_venc.c的整体分析提及的"配置视频捕获模块". 分析方法上,我们 ...

  3. 越狱第一和第二季(免费在线视频)

    在网上发现的资源,经过测试,是可以看的,而且是SWF文件,所以看起来还算是比较舒服的(对网速不太快的人来讲).最近听说这个电影是相当的流行的啊!所以,大家都赶紧来看哦~ 第一季第1集:[url]htt ...

  4. 传智播客C语言视频第二季(第一季基础上增加诸多C语言案例讲解,有效下载期为10.5-10.10关闭

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 卷 ba ...

  5. 传智播客C语言视频第二季(第一季基础上增加诸多C语言案例讲解,有效下载期为10.5-10.10关闭)

    卷 backup 的文件夹 PATH 列表 卷序列号为 00000025 D4A8:14B0 J:. │  1.txt │  c语言经典案例效果图示.doc │  ├─1传智播客_尹成_C语言从菜鸟到 ...

  6. 传智播客C语言视频第二季(第一季基础上增加诸多C语言案例讲解,有效下载期为10.5-10.10关闭)...

    卷 backup 的文件夹 PATH 列表 卷序列号为 00000025 D4A8:14B0 J:. │  1.txt │  c语言经典案例效果图示.doc │  ├─1传智播客_尹成_C语言从菜鸟到 ...

  7. 传智播客C语言视频第二季 第一季基础上增加诸多C语言案例讲解,有效下载期为10 5-10 10关闭

    分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow 卷 backup ...

  8. 跟着王进老师学开发C#篇第二季:面向对象-王进-专题视频课程

    跟着王进老师学开发C#篇第二季:面向对象-9471人已学习 课程介绍         面向对象的思想在现在程序开发中非常重要,很多刚入门的程序员没有真正理解面向对象的思想而被挡在在软件开发的门外,本次 ...

  9. 一:Greenplum5.10.2 生产环境安装配置 (系统初始化、安装准备)

    Centos7.5安装配置Greenplum5.10.2 (生产环境) 服务简介: Greenplum Master Master只存储系统元数据,业务数据全部分布在Segments上.其作为整个数据 ...

  10. Python可以这样学(第二季:tkinter案例精选)-董付国-专题视频课程

    Python可以这样学(第二季:tkinter案例精选)-3592人已学习 课程介绍         董付国老师系列教材<Python程序设计基础>(ISBN:9787302410584) ...

最新文章

  1. 【Android NDK 开发】Android Studio 的 NDK 配置 ( 源码编译配置 | 构建脚本配置 | 打包配置 | CMake 配置 | ndkBuild 配置 )
  2. java发布后功能不能用,急项目发布后java写的打印功能失效了-求解解决方法
  3. boost::system::windows_error相关的测试程序
  4. 在同一个workprocess里对两张表分别使用online update和update function module update
  5. 风机桨叶故障诊断(四) 正负样本准备——从图像中随机扣图
  6. RxSwift学习插曲--Timer补充内容
  7. vue ---- 组件
  8. Audio 加载hal (loadHwModule)
  9. linux 解压加密zip,linux 系统下 zip 的加密压缩与解压缩命令
  10. QQlook--QQ空间密码 相册密码查看工具 国庆版 V2.4
  11. 全面质量管理 TQM、六西格玛、CMMI、ISO9000 关系
  12. 马云收购士兰微_马云出手!阿里36亿拿下千方科技
  13. 关于一级域名和二级域名跨域的解决方案
  14. 2019年北航、南大、东南、上科大及本校计算机系保研
  15. 北大计算机专业研究生录取分数线,北京大学考研分数线是多少
  16. arduino数字端口输出电压可驱动多大继电器呢_「白皮书」数字信号与脉冲序列调理...
  17. dota 英雄使用 曙光酒馆《2》
  18. 有36匹马,六个跑道,用最少的次数选出最快的前3匹马
  19. 「Ceph集群部署」多机离线部署
  20. redis set集合应用场景

热门文章

  1. 实习成长之路:MySQL一: 一条SQL查询语句是如何执行的?
  2. jsp访问web-inf下的spring配置文件
  3. Android中如何实现无缝切码流
  4. 认真与随便,结果有天壤之别
  5. tomcat出现5个using_婚姻出现危机的8个迹象,日常5个细节促进夫妻情感
  6. 产品类别二级分类_医疗器械分类目录未来可能实施动态调整
  7. init函数的注意事项和细节
  8. ATM取款机java的实现--练习代码
  9. 数据库的增加,删除,更新操作--mysql
  10. docker host模式拿到nginx远程ip端口_docker网络模式实战