在fc中怎么给变量分配地址

在fc中怎么给变量分配地址,第1张

如何分配变量到指定的地址

举例:

unsigned char temp_A@0x00//定义无符号变量temp_A,强制其地址为0x00

unsigned char temp_B@0x100//定义无符号变量temp_B,强制其地址为0x100

@tiny unsigned char temp_C//定义无符号变量temp_C,由编译器自动在地址小于0x100的RAM中为其分配一个地址

@near unsigned char temp_D//定义无符号变量temp_D,由编译器自动在地址大于0xFF的RAM中为其分配一个地址

另外也可以采用伪指令"pragma"将函数或者变量定义到指定的section中,例如:

#pragma section [name] // 将下面定义的未初始化变量定义到.name section中

Unsigned char data1

Unsigned int data2

……(任何需要定义在.name section中的变量)

……

#pragma section [] // 返回到正常的section.

注意:pragma伪指令可以用来定位函数,初始化变量或者未初始化变量。这三者用不同的括号区分。

(name):代码

[name] :未初始化变量

{name}:初始化变量

如何在COSMIC C文件中使用汇编语言

在COSMIC C文件中使用汇编语言常见的方法有如下两种:使用#asm …#endasm组合格式

或_asm("…")单行格式。

举例1:

unsigned char temp_A

Void func1(void)

{

...

#asm

PUSH A

LD A,(X)

LD _temp_A,A

POP A

#endasm

...

}

注:在C嵌汇编环境下使用全局变量,要在该全局变量名称前加下划线"_"。

举例2:

Void func1(void)

{

...

_asm("rim")

_asm("nop")

...

}

如何观察RAM/FLASH/EEPROM的最终分配情况

在Project->settings->linker选项页中,将Category选为Output,再勾选Generate Map File。

点击OK按键后,再次编译链接该项目,如果成功则会在项目输出目录中(本例是在C:\STM8_NewProject1\debug 目录下)生成 .map 文件。该文件详细地列出RAM/FLASH/EEPROM的分配使用情况。

如何生成hex格式的输出文件

在Project->settings->PostBuild选项页中,在commands栏内加入下行命令:

chex –fi -o $(OutputPath)$(TargetSName).hex $(OutputPath)$(TargetSName).sm8

再次编译链接该项目,如果成功则会在项目输出目录中(本例是在C:\STM8_NewProject1\debug 目录下)生成 .hex 文件。

什么是MEMORY MODEL

STM8的C编译器支持多种存储器模式。http://tiyubisai.com/video_news/news_135621.html 用户可以根据应用的需要选择最适合的配置。可以根据需要选择采用2个字节的寻址方式(仅适用于64k以内的程序)或老迟者3字节的寻址方式。也可以规定将变量默认为定义在存储器的哪一区域:zero page内,汪察还是zero page 外。下面对几种供选择的MEMORY MODEL做简单说明。

在Project->settings->C Complier选项页中,将Category选为General,里面有一个Memory Models选项栏如下:

在下拉菜单中共有4种MEMORY MODEL可供选择:

程困含茄序地址空间在64K以内(即程序容量小于32K)

mods0,

modsl0

程序地址哦那个键在64K以上(即程序容量大于32K)

mods

modsl

MODS0 MODSL0 MODS MODSL

名称 Stack Short

短堆栈模式 Stack Long

长堆栈模式 Stack Short

短堆栈模式 Stack Long

长堆栈模式

程序地址空间 程序所用到的地址空间在64K范围内 程序所用到的地址空间超出64K范围

指针默认类型 函数指针和数据指针默认为@near (2 bytes) 函数指针默认为@far(地址为3字节);

数据指针默认为@near

全局变量默认类型 所有全局变量的地址默认为1个字节。对于地址超出1个字节的变量,必须用@near定义 所有全局变量默认为Long型。若要将变量地址定义为1个字节,必须用@tiny定义 所有全局变量的地址默认为1个字节。对于地址超出1个字节的变量,必须用@near定义 所有全局变量默认为Long型。若要将变量地址定义为1个字节,必须用@tiny定义

.lkf 文件的作用

.lkf文件在程序链接时决定如何具体分配RAM/ROM的空间。在Project Settings – Linker – Category(Input)选项页中,当"Auto"选择框被选中时,由系统自动生成.LKF文件,否则由用户指定。

当"Auto"选择框被勾选时,.lkf文件会自动生成在项目主目录下的 debug/ 和 release/ 目录中。下面以上图所示 at45DBXX Project的 lkf 文件为例,来进一步理解.lkf 。

在.lkf中,以"#"开头的行是注释行,为方便用户理解,将原注释删除,代之以中文注释如下:

# 定义(+seg)一个常量段(.const),开始(b)于0x8080,最大分配(m)0x1ff80个字节(即不超过

# 0x27FFF),为该段起名(n)为.const(和常量段的保留字同名),需要初始化的变量的初始值存

# 放于此段(-it)

+seg .const -b 0x8080 -m 0x1ff80 -n .const -it

# 定义(+seg)一个程序段(.text),紧跟(-a)在.const段后面(和.const 共同位于0x8080 –

# 0x27FFF),为该段起名(n)为. text (和程序段的保留字同名)。

+seg .text -a .const -n .text

# 定义(+seg)一个EEPROM段(.eeprom),开始(b)于0x4000,最大分配(m)0x800个字节(即不超

#过0x47FF),为该段起名(n)为. eeprom (和EEPROM段的保留字同名)。

+seg .eeprom -b 0x4000 -m 0x800 -n .eeprom

# .bsct段服务于定义在0页(地址小于0x100)以内需要初始化的全局变量(如@tiny char a = 9)

+seg .bsct -b 0x0 -m 0x100 -n .bsct

# .ubsct段服务于定义在0页(地址小于0x100)以内不需要初始化的全局变量(如@tiny char b)

+seg .ubsct -a .bsct -n .ubsct

# .bit表示位域段,定义后即可在程序中使用_Bool变量(如_Bool c = 1),-id表示该段需要初始化。

+seg .bit -a .ubsct -n .bit -id

# 这是ST7时代(STM8是基于ST7发展而来的)由于物理堆栈小,速度慢,使用内存来模拟堆栈的变通手段。

+seg .share -a .bit -n .share -is

# .data段服务于定义在0页(地址大于0xFF)以外需要初始化的全局变量(如@near char d = 8)

+seg .data -b 0x100 -m 0x1300 -n .data

# .bss段服务于定义在0页(地址大于0xFF)以内不需要初始化的全局变量(如@ near char e)

+seg .bss -a .data -n .bss

# 段定义结束,下面放置的库及Obj文件中的变量、常量、程序就按照上面的规定进行分配。

#初始化程序

crtsi0.sm8

#用户程序

Debug\main.o

# 一些必要的cosmic库

libis0.sm8

libm0.sm8

# 重定义常量段,开始于0x8000,用于放置中断向量表(STM8硬件决定此位置)

# –k 用于程序冗余代码优化,详情可参考cosmic用户手册。

+seg .const -b 0x8000 –k

# 中断向量

Debug\stm8_interrupt_vector.o

#定义了三个变量,用于系统初始化

+def __endzp=@.ubsct # end of uninitialized zpage

+def __memory=@.bss # end of bss segment

+def __stack=0x17ff # 不同的芯片__stack内容不同,由系统自动生成

如何实现位 *** 作

Cosmic C 编译器支持位变量的 *** 作,可以将其定义成 _Bool类型。_Bool类型的变量只包含两种值true(1)或者false(0)。若将一个表达式赋值给_Bool变量,则编译器会将表达式与0做比较,然后将布尔值赋给_Bool变量。因此,任何整型或者表达式的值都可以赋给_Bool变量。但是,布尔变量不能定义位数组,只能定义成结构体或者联合。而且,_Bool变量会被打包成字节的形式。

编译器会将所有的全局_Bool变量打包成字节形式,存放在.bit section中。局部_Bool变量也会被打包成字节形式。但是_Bool类型的参数会被扩展成一个单字节。

具体的关于位变量的定义和使用可参考如下例子:

定义位变量:

_Bool in_range

_Bool p_valid

char *ptr

使用位变量:

in_range = (value >= 10) &&(value <= 20)

p_valid = ptr/* p_valid is true if ptr not 0 */

if (p_valid &&in_

在使用位变量时,若程序编译时提示如下错误:

#error clnk Debug\example.lkf:1 no default placement for segment .bit

The command: "clnk -l"C:\Program Files\COSMIC\CXSTM8_16K_4.2.10\Lib" -o Debug\example.sm8 -mDebug\example.map -sa Debug\example.lkf " has failed, the returned value is: 1

exit code=1.

实际上是由于,在项目中没有定义.bit section。可按照如下步骤,手工添加.bit section:

打开项目链接配置窗口:Project - Settings - Linker,选择 Input 目录项

问题是由于程序代码大于共用flash引起的,需要把部分代码放到Bank(bank0或者其他)中。

解决办法:

(1)创建一个lk.dr文件,然后编侍蚂巧入:merge segment1 :=BANK0

merge segment2 :=BANK1

(2)把lk.dr添加到工程中;

(3)把要放在bank中的C文件,在C代码文件的物辩头老键顶加入

#pragma section @@CNST segment1

然后编译,观察map文件再做调整。

以上方法由QQ群:瑞萨(NEC)应用交流 173700459 古董大神提供。

问题是我这样 *** 作了,编译后查看map发现有以下疑问:

78K/0 Series Linker V4.01 Date:22 Jan 2015 Page: 3

@@R_INIS @ROM 00085H00000H

@@CNST 00085H00000H CSEG UNITP

@@CNST @cstart00085H00000H

@@CNST MCU_Init 00085H00000H

* gap * 00085H0000AH

* gap (Not Free Area) * 0008FH00101H

@@LCODE 00190H000AFH CSEG

@@LCODE @cstart00190H00076H

@@LCODE @imul 00206H00014H

@@LCODE @hdwinit 0021AH00001H

@@LCODE exit 0021BH00024H

@@CODE 0023FH07C34H CSEG

@@CODE main 0023FH04F42H

@@CODE MCU_Init 05181H000E8H

@@CODE ZGDSP2Comm

05269H0080EH

@@CODE ZGDSPComm

05A77H0079DH

@@CODE ZGInComm 06214H0062CH

@@CODE ZGOutComm

06840H006BBH

@@CODE ZGPMVPro 06EFBH00BEAH

@@CODE ZGSamp 07AE5H0038EH

* gap * 07E73H0018DH

MEMORY=BANK0

BASE ADDRESS=08000H SIZE=04000H

OUTPUT INPUTINPUT BASE SIZE

SEGMENT SEGMENT MODULE ADDRESS

segment1 08000H0183AH CSEG UNITP

segment1 main 08000H00330H

segment1 ZGDSP2Comm

08330H00446H

segment1 ZGDSPComm

08776H00812H

segment1 ZGInComm 08F88H00108H

segment1 ZGOutComm

09090H00000H

segment1 ZGPMVPro 09090H00190H

segment1 ZGSamp 09220H0061AH

* gap * 0983AH027C6H

@@CODE都是在共用Flash

而@@CNST是指 代码中定义的常量在bank0中


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12214769.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存