• (十二)进一步掌握STVD/COSMIC


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

    举例:
    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_NewProject1debug 目录下)生成 .map 文件。该文件详细地列出RAM/FLASH/EEPROM的分配使用情况。

    如何生成hex格式的输出文件
    在Project->settings->PostBuild选项页中,在commands栏内加入下行命令:
    chex –fi -o $(OutputPath)$(TargetSName).hex $(OutputPath)$(TargetSName).sm8
    再次编译链接该项目,如果成功则会在项目输出目录中(本例是在C:STM8_NewProject1debug 目录下)生成 .hex 文件。

    什么是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
      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
    #用户程序
    Debugmain.o

    # 一些必要的cosmic库
    libis0.sm8
    libm0.sm8
    # 重定义常量段,开始于0x8000,用于放置中断向量表(STM8硬件决定此位置)
    # –k 用于程序冗余代码优化,详情可参考cosmic用户手册。
    +seg .const -b 0x8000 –k
    # 中断向量
    Debugstm8_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 Debugexample.lkf:1 no default placement for segment .bit
    The command: "clnk -l"C:Program FilesCOSMICCXSTM8_16K_4.2.10Lib" -o Debugexample.sm8 -mDebugexample.map -sa Debugexample.lkf " has failed, the returned value is: 1
    exit code=1.
    实际上是由于,在项目中没有定义.bit section。可按照如下步骤,手工添加.bit section:
    打开项目链接配置窗口:Project - Settings - Linker,选择 Input 目录项

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

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

  • 相关阅读:
    thinkphp计划任务使用cronRun-Thinkphp3.1版
    AJAX 跨域请求
    可以做外汇交易接口的网站
    thinkphp 定时执行php文件 php自动执行php文件
    关于major、minor的解释
    Codeforces Round #370 (Div. 2) A B C 水 模拟 贪心
    2016 ACM/ICPC Asia Regional Dalian Online 1006 /HDU 5873
    Codeforces Round #280 (Div. 2) A B C 暴力 水 贪心
    codevs 1299 线段树 区间更新查询
    Codeforces Round #260 (Div. 2) A B C 水 找规律(大数对小数取模) dp
  • 原文地址:https://www.cnblogs.com/zhangshenghui/p/7447400.html
Copyright © 2020-2023  润新知