72

帖子

0

TA的资源

一粒金砂(初级)

21
 
可以指定将一个模块(文件)的代码放在指定的空间(http://www.keil.com/support/man/docs/bl51/bl51_code.htm),全局变量指定位置很好办不用多说了,局部变量有意义吗?不知你是怎么考虑的?!!

回复

83

帖子

0

TA的资源

一粒金砂(初级)

22
 
引用 13 楼 iwillalwaysloveyou 的回复:
我想重用ROM里的代码



keil支持重入函数

重入函数,又叫再入函数,是一种可以在函数体内不直接或间接调用其自身的一种函数。
再入函数可被递归调用,无论何时,包括中断函数在内的任何函数都可以调入。再入函数在
C51编译时使用的是模拟栈。
函数说明: 函数名(形式参数表) reentrant
注意事项:
1、再入函数不能传递bit类型参数。
2、与PL/M51兼容的函数不能具有reentrant,这样也不能调用再入函数。
3、在编译时:再入函数建立的是模拟堆栈区,small模式下模拟堆栈区位于idata
区,compact模式下模拟堆栈区位于pdata区,large模式下模拟堆栈区位于xdata区.
4、在同一程序中可以定义和使用不同存储器模式的再入函数,任意模式的再入函数不能调
用不同存储器模式的再入函数,但可以调用普通函数。
5、实际参数可以传递给间接调用的再入函数。无再入属性的间接调用函数不能包含调用参
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

23
 
引用 17 楼 iwillalwaysloveyou 的回复:
掩膜芯片,同时提供ROM和EEPROM,

我的cos代码最终是要放到ROM里,

现在想支持后下载cos替换ROM里的cos,

并且后下载的cos能重用ROM里的部分代码


这个也不用这么复杂吧,你要重用的那些代码是不会再修改的吧,直接将这些代码放到ROM中指定位置直接调用不就行了。一个芯片有很多应用,芯片不可能提供所有应用代码,将固定的模块功能打包成lib就行了。用户应用代码可以放在外部存储芯片上,Mask ROM提供基本应用的Code.
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(中级)

24
 
考虑到空间及效率问题,不使用重入函数。

楼上你用Keil C51开发过程序吗?
C51的非重入函数局部变量的地址是固定的。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

25
 
重入函数非迫不得已不会用,说实话我写了C51的代码如果以行来计算的话,起码有个二三十万行吧,还没有用过reentrant,但是了解是必要的.还有局部变量是可以指到不同区域的,如XDATA, 固定地址你能确定吗?
 
 
 

回复

95

帖子

0

TA的资源

一粒金砂(初级)

26
 
引用 24 楼 jlctt 的回复:
重入函数非迫不得已不会用,说实话我写了C51的代码如果以行来计算的话,起码有个二三十万行吧,还没有用过reentrant,但是了解是必要的.还有局部变量是可以指到不同区域的,如XDATA, 固定地址你能确定吗?


局部变量是可以指到不同区域,这个没错。
我所说的固定,指的是芯片掩膜之后。

我需要把某些模块的全局变量和局部变量全部集中起来放到一个固定位置。
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

27
 
我看了编译器手册,没有提供支持,应该是没什么好办法解决这个问题
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

28
 
Absolute Variable Location.
Variables may be located at absolute memory locations in your C program
source modules using the _at_ keyword. The usage for this feature is:
type memory_space variable_name _at_ constant;
where:
memory_space is the memory space for the variable. If missing from the
declaration, the default memory space is used. Refer to
“Memory Models” on page 94 for more information about
the default memory space.
type is the variable type.
variable_name is the variable name.
constant is the address at which to locate the variable.
The absolute address following _at_ must conform to the physical boundaries of
the memory space for the variable. The Cx51 compiler checks for invalid
address specifications.
//例子:
struct link
{
struct link idata *next;
char code *test;
};
struct link list idata _at_ 0x40; /* list at idata 0x40 */
char xdata text[256] _at_ 0xE000; /* array at xdata 0xE000 */
int xdata i1 _at_ 0x8000; /* int at xdata 0x8000 */
void main ( void ) {
link.next = (void *) 0;
i1 = 0x1234;
text [0] = 'a';
}
//但:
2. Functions and variables of type bit cannot be located at an absolute address
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(中级)

29
 
至于代码位置要从.map文件中得到。再利用函数指针写一个头文件给用户就可以了。
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

30
 
不使用跟具体平台绑定的代码
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

31
 
最好是能通过改编译选项解决问题
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

32
 
你看看我说的这种方式能不能解决你的问题:
1,你可以看一下bootload的初始化代码,中断函数入口地址都是定义在0地址开始的地方,你可以把你的模块函数入口地址放在接下去的地方就可以通过把绝对地址赋值给指向函数的指针来调用你的函数了。建议可以看下stm32 usb IAP的示例,里面是通过绝对地址跳转到真正的main()函数,你就能明白了。
2,keil中有个定义变量后面加上__at(地址)的方式把你的变量定义到指定的位置,你可以试一下定义在最前面。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

33
 
引用 25 楼 iwillalwaysloveyou 的回复:
引用 24 楼 jlctt 的回复:
重入函数非迫不得已不会用,说实话我写了C51的代码如果以行来计算的话,起码有个二三十万行吧,还没有用过reentrant,但是了解是必要的.还有局部变量是可以指到不同区域的,如XDATA, 固定地址你能确定吗?


局部变量是可以指到不同区域,这个没错。
我所说的固定,指的是芯片掩膜之后。

我需要把某些模块的全局变量和局部变量全部集中起来放到一个固定位置。

如果你指的变量是函数体内部的局部变量,通常是分配在RAM空间的,同样的函数如果在不同的地方调用,局部变量也不一定是固定的。如果你指的变量是说一个模块的变量,在函数体外声明,要固定地址还是有办法的,除了_at_外,还可以用以下(原文出自http://leency0000.spaces.live.com/default.aspx?_c02_owner=1)方式定位:

1、函数定位:
假如要把C源文件 tools.c 中的函数
int BIN2HEX(int xx)
{
  ...
}
放在CODE MEMORY的0x1000处,先编译该工程,然后打开该工程的M51文件,在
* * *   C O D E   M E M O R Y   * * *
行下找出要定位的函数的名称,应该形如:
CODE    xxxxH     xxxxH     UNIT         ?PR?_BCD2HEX?TOOLS
然后在:
Project->Options for Target ...->BL51 Locate:Code
中填写如下内容:
?PR?_BCD2HEX?TOOLS(0x1000)
再次Build,在M51中会发现该函数已放在CODE MEMORY的0x1000处了

2、赋初值的变量定位:
要将某变量定位在一绝对位置且要赋初值,此时用 _at_ 不能完成,则如下操作:
在工程中建立一个新的文件,如InitVars.c,在其中对要处理的变量赋初值(假设是code变
量):
char code myVer = {"COPYRIGHT 2001-11"};
然后将该文件加入工程,编译,打开M51文件,若定义的是code型,则在
* * *   C O D E   M E M O R Y   * * *
下可找到:
CODE    xxxxH     xxxxH     UNIT         ?CO?INITVARS
然后在:
Project->Options for Target ...->BL51 Locate:Code
中填入:
?CO?INITVARS(0x200)
再次编译即可。

相应地,如为xdata变量,则InitVars.c中写:
char xdata myVer = {"COPYRIGHT 2001-11"};
然后将该文件加入工程,编译,打开M51文件,在
* * *  X D A T A   M E M O R Y  * * *
下可找到:
XDATA   xxxxH     xxxxH     UNIT         ?XD?INITVARS
然后在:
Project->Options for Target ...->BL51 Locate:Xdata
中填入:
?XD?INITVARS(0x200)
再次编译即可。相应地,若定义的是data/idata等变量,则相应处理即可。

3、若有多个变量或函数要进行绝对地址定位,则应按地址从低到高的顺序排列。
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(初级)

34
 
在KEIL FOR ARM中,我是用分散加载文件来做的,用分散加载文件可以任意分配指定你想要的变量,模块所处的位置。

KEIL C51可能也有这样的功能,你可以查查相关帮助文档。
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(中级)

35
 
to iwillalwaysloveyou,
我也有过这样的疑问,基本上在KEIL工具上,要想函数的临时变量不要采用固定的地址,只有可重入(reentrant),不过可重入后代码就变大许多,可以说keil没有考虑好把部分模块打包lib后时,采用堆栈这种模式来调用,或者是没有优化好吧。
IAR Embedded Workbench for MCS-51就基本可以解决这个问题,IAR编译出来的程序,局部变量采用的堆栈的模式,是完全可以满足你的要求。
只有写过一些MASKROM程序的人才有这样的体会,我们现在就在用IAR的模式,IAR就是入门难一点,IAR有点GCC的风格,程序的连接过程完全能有开发者自主控制住你的程序。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表