在前面,我们使用汇编程序来实现了重定位和清bss段,本节我们将使用C语言,实现重定位和清除bss段。
1.打开start.S把原来的汇编代码删除改为调用C函数
/* 重定位text, rodata, data段整个程序 */
mov r1, #0
ldr r2, =_start /* 第1条指令运行时的地址 */
ldr r3, =__bss_start /* bss段的起始地址 */
cpy:
ldr r4, [r1]
str r4, [r2]
add r1, r1, #4
add r2, r2, #4
cmp r2, r3
ble cpy
/* 清除BSS段 */
ldr r1, =__bss_start
ldr r2, =_end
mov r3, #0
clean:
str r3, [r1]
add r1, r1, #4
cmp r1, r2
ble clean
改为:
/* 重定位text, rodata, data段整个程序 */
mov r0, #0
ldr r1, =_start /* 第1条指令运行时的地址 */
ldr r2, =__bss_start /* bss段的起始地址 */
sub r2, r2, r1 /*长度*/
bl copy2sdram /* src, dest, len */
/* 清除BSS段 */
ldr r0, =__bss_start
ldr r1, =_end
bl clean_bss /* start, end */
1、在init.c 实现如上两个C函数
void copy2sdram(volatile unsigned int *src, volatile unsigned int *dest, unsigned int len) /* src, dest, len */
{
unsigned int i = 0;
while (i < len)
{
*dest++ = *src++;
i += 4;
}
}
void clean_bss(volatile unsigned int *start, volatile unsigned int *end) /* start, end */
{
while (start <= end)
{
*start++ = 0;
}
}
汇编中,为C语言传入的参数,依次就是R1、R2、R3。
编译,烧写运行没有问题。
我们假设不想汇编传入参数,而是C语言直接取参数。
1、修改start.S 跳转到C函数不需要任何参数
bl sdram_init
//bl sdram_init2 /* 用到有初始值的数组, 不是位置无关码 */
/* 重定位text, rodata, data段整个程序 */
bl copy2sdram
/* 清除BSS段 */
bl clean_bss
2、修改链接脚本,让__code_start 等于当前地址,也就是这里的0x30000000
SECTIONS
{
. = 0x30000000;
__code_start = .; //定义__code_start地址位当前地址
. = ALIGN(4);
.text :
{
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) *(.COMMON) }
_end = .;
}
3、修改init.c 用函数来获取参数
void copy2sdram(void)
{
/* 要从lds文件中获得 __code_start, __bss_start
* 然后从0地址把数据复制到__code_start
*/
extern int __code_start, __bss_start;//声明外部变量
volatile unsigned int *dest = (volatile unsigned int *)&__code_start;
volatile unsigned int *end = (volatile unsigned int *)&__bss_start;
volatile unsigned int *src = (volatile unsigned int *)0;
while (dest < end)
{
*dest++ = *src++;
}
}
void clean_bss(void)
{
/* 要从lds文件中获得 __bss_start, _end
*/
extern int _end, __bss_start;
volatile unsigned int *start = (volatile unsigned int *)&__bss_start;
volatile unsigned int *end = (volatile unsigned int *)&_end;
while (start <= end)
{
*start++ = 0;
}
}
编译烧写运行 ,没有问题。
总结:
C函数怎么使用lds文件总的变量abc?
1、在C函数中声明改变量为extern外部变量类型,比如extern int abc;
2、使用时,要取址,比如:int *p = &abc;//p的只即为lds文件中abc的值
汇编文件中可以直接使用外部链接脚本中的变量,但C函数中要加上取址符号。
解释一下原因:
C函数中,定义一个全局变量int g_i;程序中必然有4字节的空间留出来给这个变量g_i
假如我们的lds文件中有很多变量
lds{
a1 = ;
a2 = ;
a3 = ;
...
}
如果我们C程序只用到几个变量,完全没必要全部存储lds里面的所有变量,C程序是不保存lds中的变量的。
对于万一要用到的变量,编译程序时,有一个symbol table符号表:
如何使用symbol table符号表?
1、对于常规变量g_i,得到里面的值,使用&g_i得到addr;
2、为了保持代码的一致,对于lds中的a1,使用&a1得到里面的值;
结论:
1、C程序中不保存lds文件中的变量,lds再大也不影响;
2、借助symbol table保存lds的变量,使用时加上”&”得到它的值,链接脚本的变量要在C程序中声明为外部变量,任何类型都可以;
上一篇:S3c2440代码重定位详解5---代码重定位与位置无关码
下一篇:S3c2440ARM异常与中断体系详解1---概念引入与处理流程
推荐阅读
史海拾趣
对于恒温箱控制器电路,网友可能会有多种问题,以下是一些常见问题及其详细回答:
一、恒温箱控制器电路的基本原理是什么?
回答:
恒温箱控制器电路的基本原理是通过温度传感器(如热敏电阻、热电偶等)实时检测恒温箱内的温度,并将检测到的温度信号转换为电信号(如电压或电流信号)。这个电信号随后被送入控制器中进行处理,与预设的温度值进行比较。如果检测到的温度高于或低于预设值,控制器会发出指令,通过调节加热元件(如电热丝、加热管等)或制冷元件(如压缩机、半导体制冷片等)的工作状态,使恒温箱内的温度回到预设值,从而实现恒温控制。
二、恒温箱控制器电路常见的故障有哪些?
回答:
恒温箱控制器电路常见的故障包括但不限于以下几种:
- 温度显示异常:
- 可能原因:温度传感器损坏、控制器内部电路故障、显示屏故障等。
- 解决方法:检查并更换损坏的温度传感器、修复或更换控制器内部故障电路、更换显示屏等。
- 温度控制不准确:
- 可能原因:控制器参数设置错误、温度传感器位置不当、加热/制冷元件故障等。
- 解决方法:重新校准控制器参数、调整温度传感器位置、检查并修复加热/制冷元件等。
- 控制器无法启动:
- 可能原因:电源故障、控制器内部保险丝熔断、电路板短路等。
- 解决方法:检查电源是否正常、更换熔断的保险丝、修复电路板短路等。
三、如何检查恒温箱控制器电路是否正常工作?
回答:
检查恒温箱控制器电路是否正常工作,可以按照以下步骤进行:
- 检查电源:
- 确认电源插头是否牢固插入插座,电源线是否完好无损。
- 使用万用表测量电源电压,确保在控制器要求的范围内。
- 检查温度传感器:
- 使用万用表测量温度传感器的电阻值或电压值,与标准值进行比较,判断传感器是否正常。
- 检查传感器与控制器之间的连接是否牢固可靠。
- 检查控制器显示:
- 观察控制器显示屏上的温度读数是否准确,有无异常显示。
- 检查加热/制冷元件:
- 检查加热/制冷元件是否正常工作,可以通过观察其工作状态或使用万用表测量其电流/电压值来判断。
- 进行功能测试:
- 设置一个预设温度值,观察恒温箱是否能准确达到并保持在预设温度。
- 如果条件允许,可以使用更精确的温度测量设备(如高精度温度计)对恒温箱内的温度进行校验。
四、如何维护和保养恒温箱控制器电路?
回答:
为了保持恒温箱控制器电路的长期稳定工作,可以进行以下维护和保养工作:
- 定期清洁:
- 定期清洁恒温箱内部和外部的灰尘和污垢,防止对控制器电路造成不良影响。
- 清洁时应断开电源,并使用合适的清洁工具和清洁剂。
- 检查连接:
- 定期检查温度传感器、加热/制冷元件与控制器之间的连接是否牢固可靠,如有松动应及时紧固。
- 校准参数:
- 定期对控制器进行校准,确保温度读数准确可靠。
- 校准时应按照控制器的使用说明书或生产厂家的建议进行操作。
- 更换老化部件:
- 对于已经老化或损坏的部件(如温度传感器、加热/制冷元件等),应及时进行更换。
- 注意使用环境:
- 恒温箱应放置在通风良好、干燥清洁的环境中,避免阳光直射和潮湿环境对控制器电路造成损害。
- 定期维护:
- 定期对恒温箱进行全面检查和维护,包括控制器电路、加热/制冷系统、进出料装置等部分。
- 维护时应按照设备的操作手册和生产厂家提供的维护保养指导进行。
随着全球对环保问题的日益关注,EPIGAP公司也开始注重绿色环保和可持续发展。公司积极采用环保材料和生产工艺,减少生产过程中的污染物排放。同时,EPIGAP还加大了对可再生能源的研发力度,推动公司向绿色、低碳、循环发展的方向迈进。这一战略不仅符合全球环保趋势,也为公司赢得了良好的社会声誉。
随着业务的发展,CTC公司意识到全球化布局的重要性。公司开始在全球范围内寻找合适的合作伙伴和投资机会,以拓展自身的业务范围和市场影响力。同时,CTC公司还加强了对国际市场的调研和分析,以更好地适应不同地区的市场需求和文化差异。这一全球布局策略使得CTC公司的竞争力得到了进一步提升。
在快速发展的过程中,Erocore意识到供应链管理的重要性。公司开始优化供应链流程,降低采购成本,提高生产效率。通过与供应商建立长期稳定的合作关系,Erocore在保证产品质量的同时,实现了成本的有效控制。这一举措为公司在激烈的市场竞争中赢得了更多的优势。
近年来,生成式AI技术的快速发展为网络安全带来了新的变革。Defender Security公司紧跟这一趋势,将生成式AI技术应用于网络安全领域。他们利用生成式AI技术来模拟和预测网络攻击行为,从而提前发现潜在的安全威胁。通过不断的技术创新和应用实践,Defender Security在网络安全领域取得了显著的成果。
2010年至2011年将有可能实现商用。 从2008年1月1日起,美国国防部将全面切换到IPv6网络,2008年6月,美国联邦政府也将全面切换到IPv6网络,这将对IPv6的商用产生巨大的影响。而以CERNET2为代表的我国基于IPv6的下一代互联网示范工程CNGI在网络测试 ...… 查看全部问答∨ |
|
作为过来人思前想后,我感到完全有责任将发自心底的感受传递给年轻一代,“一个企业家心灵深处渴望优秀人才的卓越追求和深层次的叹息、痛苦和感受”。您们千万不要等到毕业求职时才觉得自己能力太差,世界上从来就没有后悔药。当然,如果您现在看了 ...… 查看全部问答∨ |
|
有不少的在校的大学生写信给我,问在学校里应该学习什么电子知识.就业形势越来越严峻,不光是在中国,全球都一样,全球经济的发展速度放慢,至少会持续几年的时间.半导体产业目前进入低潮,很多公司裁员和亏损.但是技术还是在不断进步,摩尔定律还在起作用 ...… 查看全部问答∨ |
|
这辆Hyperbike堪称人动力车中的坦克,乘坐它出行,再跟儿童车相撞的时候,大概是再也不会输掉啦。当然,驱动它运转需要全身肌肉的参与,耗费的体力也是儿童车所无法比较的。它的这一优点——并非指它能撞赢儿童车——使得它获得了美国国家航空航天 ...… 查看全部问答∨ |
|
VS2005里面调试的时候怎么看全局的静态变量(局部变量看起来很简单)?看内存?那全局的静态变量在内存里面的地址怎么计算? VS2005里面调试的时候怎么看全局的静态变量(局部变量看起来很简单)?看内存?那全局的静态变量在内存里面的地址怎么计算?看EXE文件对应生成的MAP文件吗?… 查看全部问答∨ |
超高分求助:500分求wince 5下nor flash的分区问题 各位高手,现在有这样一个问题,急着解决,高分求助,在线等待 环境:wince 5,pb5 XScale PXA270, 32M SDRAM, 32M Nor Flash,现在生成的nk的大小为20MB左右,想用剩下的空间做文件存储用,如何操作?… 查看全部问答∨ |