当前位置: 首页 > news >正文

Tiny4412之C语言实现流水灯,Tiny4412裸机程序[3]

在前边我们使用汇编完成了一个流水灯实验: Tiny4412汇编流水灯代码,Tiny4412裸机LED操作

 

 

----

 

-

 

--

--

--

-

 --

 

--

修改:

# ${MKBL2} ${SOURCE_FILE} bl2.bin 14336                                
 ./${MKBL2} ${SOURCE_FILE} bl2.bin 14336

或者:

MKBL2=my_mkbl2改成MKBL2=./my_mkbl2

 

 必须有:chmod +x my_mkbl2

chmod 777 my_mkbl2

然后 查看下权限

 ls -l my_mkbl2

变黄即可

 

后编译成功

root@phone-desktop:/opt/FriendlyARM/tiny4412/bare/led# sudo ./sd_fusing.sh /dev/sdc ../led/led.bin
/dev/sdc reader is identified.
./sd_fusing.sh: 59: ./sd_fusing.sh: my_mkbl2: not found
---------------------------------------
BL1 fusing
记录了16+0 的读入
记录了16+0 的写出
8192字节(8.2 kB)已复制,0.0270466 秒,303 kB/秒
---------------------------------------
BL2 fusing
dd: 正在打开"./bl2.bin": 没有那个文件或目录
Write BL2 Error!
./sd_fusing.sh: 91: exit: Illegal number: -1
root@phone-desktop:/opt/FriendlyARM/tiny4412/bare/led# sudo ./sd_fusing.sh /dev/sdc ../led/led.bin
/dev/sdc reader is identified.
---------------------------------------
BL1 fusing
记录了16+0 的读入
记录了16+0 的写出
8192字节(8.2 kB)已复制,0.0233195 秒,351 kB/秒
---------------------------------------
BL2 fusing
记录了28+0 的读入
记录了28+0 的写出
14336字节(14 kB)已复制,0.0504196 秒,284 kB/秒
---------------------------------------
source file image is fused successfully.
Eject SD card and insert it to Exynos 4412 board again.
root@phone-desktop:/opt/FriendlyARM/tiny4412/bare/led#

 

 

设置权限后,解决上面问题。

但是,汇编语言可读性太差,在这一节我们用 C语言来实现了同样的功能,而以后的试验也尽量用 C语言实现。

我们在编写上位机程序时,C语言程序执行的第一条指令,并不在main函数中。生成一个 C程序的可执行文件时,编译器通常会在我们的代码中加上几个被称为启动文件的代码—— crtl.o 、crti.o、crtend.o 、crtn.o 等,它们是标准库文件。这些代码设置C程序的堆栈等,然后调用 main 函数。它们依赖于操作系统,在裸板上这些代码无法执行,所以需要自己写一个。

这段代码很简单, 关键指令只有2条。自己编写的 start .S启动文件内容如下:

.text
.globl _start
_start:
 ldr sp, =0x02027800 
 
// 调用C函数之前必须设置栈,栈用于保存运行环境,给局部变量分配空间
// 参考ROM手册P14, 我们把栈指向BL2上方1K处(1K已经够用),
// 即:0x02020000 (iRAM基地址) + 5K(iROM代码用) + 8K(BL1用) + 16K(BL2用) + 1K(用作栈))
 
 bl main  // 调用main函数(main这个名称不是固定的,可以随意改)
 
halt_loop:
 b halt_loop

 

它在第 4行设置好栈指针后,就可以通过第8行调用C函数 main了--------------- C函数执行前,必须设置栈。

 问:CPU不是有看门狗嘛?为什么没有看到关看门狗的代码?这样程序能正常运行吗?

答:在上一篇文章《Exynos 4412的启动过程分析》中,我们已经介绍过了,在执行我们的程序前,CPU会首先执行iROM中的代码和BL1的代码,在这两部分程序中会关闭看门狗。

其实我们自己关闭看门狗也很简单,只需往寄存器WTCON写入0即可;

问:为什么调用C函数要设置栈?

答:1.  栈的整体作用

1)  保存现场;

2)  传递参数:汇编代码调用C函数时,需传递参数;

3)  保存临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量;

2.  详细解释

1)保存现场

现场,意思就相当于案发现场,总有一些现场的情况,要记录下来的,否则被别人破坏掉之后,你就无法恢复现场了。而此处说的现场,就是指CPU运行的时候,用到了一些寄存器,比如r0,r1等等,对于这些寄存器的值,如果你不保存而直接跳转到子函数中去执行,那么很可能就被其破坏了,因为其函数执行也要用到这些寄存器。因此,在函数调用之前,应该将这些寄存器等现场,暂时保持起来(入栈push),等调用函数执行完毕返回后(出栈pop),再恢复现场。这样CPU就可以正确的继续执行了。保存寄存器的值,一般用的是push指令,将对应的某些寄存器的值,一个个放到栈中,把对应的值压入到栈里面,即所谓的压栈。然后待被调用的子函数执行完毕的时候,再调用pop,把栈中的一个个的值,赋值给对应的那些你刚开始压栈时用到的寄存器,把对应的值从栈中弹出去,即所谓的出栈。其中保存的寄存器中,也包括lr的值(因为用bl指令进行跳转的话,那么之前的PC的值是存在lr中的),然后在子程序执行完毕的时候,再把栈中的lr的值pop出来,赋值给PC,这样就实现了子函数的正确的返回。

2)传递参数

C语言进行函数调用的时候,常常会传递给被调用的函数一些参数,对于这些C语言级别的参数,被编译器翻译成汇编语言的时候,就要找个地方存放一下,并且让被调用的函数能够访问,否则就没发实现传递参数了。对于找个地方放一下,分两种情况。一种情况是,本身传递的参数不多于4个,就可以通过寄存器r0~r3传送参数。因为在前面的保存现场的动作中,已经保存好了对应的寄存器的值,那么此时,这些寄存器就是空闲的,可以供我们使用的了,那就可以放参数。另一种情况是,参数多于4个时,寄存器不够用,就得用栈了。

3)临时变量保存在栈中

包括函数的非静态局部变量以及编译器自动生成的其他临时变量。

 

现在,我们可以很容易写出控制 LED 的程序了。毕竟是用C语言嘛,相当的灵活。 main 函数在 led.c 文件中,代码如下:

#define GPM4CON (*(volatile unsigned int *)0x110002E0)
#define GPM4DAT (*(volatile unsigned int *)0x110002E4)
 
void delay(volatile int time)
{
      for(; time > 0; time-- )
;
}
 
int main(void)
{
unsigned long tmp = 0;
int i = 0;
 
/*
* GPM4_0-GPM4_3 设置为输出功能
*/
 
tmp = GPM4CON;
tmp &= ~0xffff;
tmp |= 0x1111;
GPM4CON = tmp;
 
/*
* 实现流水灯
*/
 
while(1)
{
GPM4DAT = i;
if (++i == 16)
i = 0;
delay(9999999);
}
 
return 0;
}

 

来看看Makefile:

objs := start.o led.o
led.bin : $(objs)
arm-linux-ld -Tled.lds -N -o led.elf $^
arm-linux-objcopy -O binary -S led.elf $@
arm-linux-objdump -D -m arm led.elf > led.dis
 
%.o:%.c
arm-linux-gcc -Wall -marm -c -O2 -o $@ $<
 
%.o:%.S
arm-linux-gcc -Wall -marm -c -O2 -o $@ $<
 
clean:
rm -f *.dis *.bin *.elf *.o

 

 

执行 make 命令时,它的目是去生成第1个目标,即 led.bin ;

led.bin 依赖于start.o 和 led.o,所以要先生成这 2个.o 文件;

start.o 依赖于start.S ,符合第 11 行的规则,会使用第 12 行的命令生成start.o ;

类似的, led.o 依赖于led.c ,符合第 8行的规则,会使用第 9行的命令生成 led.o ;

当这 2个.o 文件都生成之后,就会执行第 4~6行的命令生成 led.bin文件: 第 4行将编译得到的 .o 文 件连接为led.elf

可执行程序,第 5行是生成二进制格式的可执行程序,第 6行是得到反汇编程序以供查看。

链接脚本还和汇编流水灯一样。

 

好了,下面开始验证我们的程序了。

1.将程序源码上传到服务器,并执行make,生成led.bin文件。

2.借鉴上一个实验的步骤,将程序烧写到SD卡。

3.将SD卡插到Tiny4412开发板,上电即可看到流水灯效果(和汇编流水灯效果一样)。

完整的程序下载地址(解压密码:WWW.techbulo.Com):

原文:http://www.techbulo.com/1347.html

 

 

 

 

 

 

---

转载于:https://www.cnblogs.com/Ph-one/p/4547424.html

相关文章:

  • sudo: ./sd_fusing.sh:找不到命令
  • 2.2linux内核移植简介
  • linux0.11文件分析
  • Linux内核3.0移植并基于Initramfs根文件系统启动
  • linux系统灵活运用灯[android课程3]
  • linux ramdisk
  • fork()和vfork()区别
  • linux上进程状态查询
  • LINUX进程优先级实现
  • linux中应用程序main函数中没有开辟进程的,它应该在那个进程中运行呢?
  • Linux上程序执行的入口--Main
  • minitools
  • Linux内核与根文件系统的关系1
  • linux应用程序问题
  • linux问题
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • [译]如何构建服务器端web组件,为何要构建?
  • 【前端学习】-粗谈选择器
  • css系列之关于字体的事
  • Java编程基础24——递归练习
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • Spark学习笔记之相关记录
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • Web Storage相关
  • WePY 在小程序性能调优上做出的探究
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 技术:超级实用的电脑小技巧
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 移动端 h5开发相关内容总结(三)
  • 硬币翻转问题,区间操作
  • 通过调用文摘列表API获取文摘
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​什么是bug?bug的源头在哪里?
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • $.ajax,axios,fetch三种ajax请求的区别
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (4)事件处理——(7)简单事件(Simple events)
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (三) diretfbrc详解
  • (转)拼包函数及网络封包的异常处理(含代码)
  • .form文件_一篇文章学会文件上传
  • .net 获取url的方法
  • .net 微服务 服务保护 自动重试 Polly
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
  • .Net多线程总结
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • [BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)
  • [BZOJ1053][HAOI2007]反素数ant
  • [Flutter]WindowsPlatform上运行遇到的问题总结
  • [HackMyVM]靶场Boxing