进一步掌握STVD/COSMIC

2024-02-06 05:18
文章标签 掌握 进一步 cosmic stvd

本文主要是介绍进一步掌握STVD/COSMIC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自:http://www.waveshare.net/article/STM8-3-1-10.htm


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

举例:
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 文件。

生成S19格式的输出文件

chex -o $(OutputPath)$(TargetSName).s19 $(OutputPath)$(TargetSName).sm8

什么是MEMORY MODEL
STM8的C编译器支持多种存储器模式。用户可以根据应用的需要选择最适合的配置。可以根据需要选择采用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

MODS0MODSL0MODSMODSL
名称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 目录项

在Zero page 或者 Ram 里面定义一个.bit section.

然后重新编译一下就可以了。

进一步掌握STVD/COSMIC

这篇关于进一步掌握STVD/COSMIC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/683228

相关文章

轻松掌握python的dataclass让你的代码更简洁优雅

《轻松掌握python的dataclass让你的代码更简洁优雅》本文总结了几个我在使用Python的dataclass时常用的技巧,dataclass装饰器可以帮助我们简化数据类的定义过程,包括设置默... 目录1. 传统的类定义方式2. dataclass装饰器定义类2.1. 默认值2.2. 隐藏敏感信息

生信代码入门:从零开始掌握生物信息学编程技能

少走弯路,高效分析;了解生信云,访问 【生信圆桌x生信专用云服务器】 : www.tebteb.cc 介绍 生物信息学是一个高度跨学科的领域,结合了生物学、计算机科学和统计学。随着高通量测序技术的发展,海量的生物数据需要通过编程来进行处理和分析。因此,掌握生信编程技能,成为每一个生物信息学研究者的必备能力。 生信代码入门,旨在帮助初学者从零开始学习生物信息学中的编程基础。通过学习常用

如何掌握面向对象编程的四大特性、Lambda 表达式及 I/O 流:全面指南

这里写目录标题 OOP语言的四大特性lambda输入/输出流(I/O流) OOP语言的四大特性 面向对象编程(OOP)是一种编程范式,它通过使用“对象”来组织代码。OOP 的四大特性是封装、继承、多态和抽象。这些特性帮助程序员更好地管理复杂的代码,使程序更易于理解和维护。 类-》实体的抽象类型 实体(属性,行为) -》 ADT(abstract data type) 属性-》成

JAVA初级掌握的J2SE知识(二)和Java核心的API

/** 这篇文章送给所有学习java的同学,请大家检验一下自己,不要自满,你们正在学习java的路上,你们要加油,蜕变是个痛苦的过程,忍受过后,才会蜕变! */ Java的核心API是非常庞大的,这给开发者来说带来了很大的方便,经常人有评论,java让程序员变傻。 但是一些内容我认为是必须掌握的,否则不可以熟练运用java,也不会使用就很难办了。 1、java.lang包下的80%以上的类

JAVA初级掌握的J2SE知识(一)

时常看到一些人说掌握了Java,但是让他们用Java做一个实际的项目可能又困难重重,在这里,笔者根据自己的一点理解斗胆提出自己的一些对掌握Java这个说法的标准,当然对于新手,也可以提供一个需要学习哪些内容的参考。另外这个标准仅限于J2SE部分,J2EE部分的内容有时间再另说。 1、语法:必须比较熟悉,在写代码的时候IDE的编辑器对某一行报错应该能够根据报错信息知道是什么样的语法错误并且知道

作为刚从事Java开发的小白,需要掌握哪些技能

作为一个刚踏入Java开发世界的小白,面对各种技术和工具,你可能会觉得有点不知所措。但是别担心,我会给你一个简单清晰的路线图,让你可以有条不紊地掌握基本技能,逐步成长为一名Java开发者。 1. 扎实的Java基础 Java的基础是你迈向高级开发的重要基石,建议从以下几个方面着手: 语法和基础概念:比如变量、条件语句、循环、方法、数组、面向对象编程(OOP)等等。这些基础如同建房子的地基,越

掌握Hive函数[2]:从基础到高级应用

目录 高级聚合函数 多进一出 1. 普通聚合 count/sum... 2. collect_list 收集并形成list集合,结果不去重 3. collect_set 收集并形成set集合,结果去重  案例演示 1. 每个月的入职人数以及姓名  炸裂函数  概述  案例演示 1. 数据准备 1)表结构 2)建表语句 3)装载语句 2. 需求 1)需求说明 2)答

掌握Go语言中的时间与日期操作

Go语言中的时间与日期操作 在编写程序时,处理时间和日期看似是一项无关紧要的任务,但在需要同步多个任务或从文本文件中读取时间时,它的重要性便凸显出来。Go语言中的time包为我们提供了丰富的时间与日期操作功能。本文将详细介绍如何在Go语言中解析时间与日期字符串、在不同的格式之间进行转换,以及如何按照所需的格式输出时间和日期。 初识time包 在学习如何解析字符串并将其转换为时间或日期之前,我

你读文献的方式可能错了!掌握这些技巧,让阅读事半功倍!

我是娜姐 @迪娜学姐 ,一个SCI医学期刊编辑,探索用AI工具提效论文写作和发表。 科研新手如何精读一篇论文? 很多科研新手,一上来就疯狂下载几十上百篇文献。囫囵吞枣看完了,还是什么都不知道,大脑一片空白。究竟该如何读文献收获最大? 大佬说,要积极阅读、频繁阅读。 什么是积极阅读? 相比被动阅读,积极阅读是指在阅读之前准备好问题、设置阅读目标、保持批判性,收获更多、进步更大的一种阅读

“掌握Linux网络编程艺术,构建跨平台的网络通信解决方案!“#Linux系统编程之网络编程

"掌握Linux网络编程艺术,构建跨平台的网络通信解决方案!"#Linux系统编程之网络 前言预备知识一、 网络编程概述1.1 网络编程概述图1.2 TCP/UDP对比(面试)1.3 端口号的作用 二、 字节序2.1 大端字节序(Big-Endian)2.2 小端字节序(Little-Endian)2.3 字节序的重要性2.4 字节序转换函数2.5 字节序示意图 三、 socket编程步骤四