合泰半导体股份有限公司 技术讲座 - Holtek V3 C Compiler介绍 主讲人:王幼端 2017/06/15.

Slides:



Advertisements
Similar presentations
C++语言程序设计教程 第5章 构造数据类型 第6章 C++程序的结构.
Advertisements

现代电子技术实验 ——综合实验之单片机部分
基本概論 Basic concepts.
第四章 招聘录用.
C语言程序设计 主讲教师 :张群燕 电话:
教 师:曾晓东 电 话: E_mail: 计算机软件技术基础 教 师:曾晓东 电 话: E_mail:
Loops.
Memory Pool ACM Yanqing Peng.
第一章 C语言概述 计算机公共教学部.
编译原理上机实习
2017/3/22 如何用C 来完成SN8系列芯片的程序设计 2017/3/22.
雷 霆 战 机 By—谷恩轩&余万全.
《计算机操作员》精品 课件 淮南市潘集职教中心
4-10 STM Timer/Counter 與比較吻合輸出
C语言程序设计 第十二章 位运算.
Introduction to the C Programming Language
第二章 C# 基础知识.
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
编译原理与技术 类型检查 2018/11/21 《编译原理与技术》-类型检查.
微 電 腦 實 驗 Megawin MPC82G516 操作與環境設定.
单片机原理与应用 C/C++在现代数字计算机上的实现.
C 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
C++ 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
STRUCTURE 授課:ANT 日期:2010/5/12.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
Function.
Object-Oriented Programming in C++ 第一章 C++的初步知识
第三章 C++中的C 面向对象程序设计(C++).
第 6 章 函式.
程序设计专题一 结构化程序设计与递归函数 主讲教师: 刘新国.
fp=fopen("CD2.dat","wb"); fwrite(&min,8,1,fp); fclose(fp);
Ch9 Communicating with Hardware
周国运 Keil C51应用 主 页:
第五章 C/C++及汇编语言的混合编程 5.1 ARM C/C++编译器 5.2 在C/C++程序中内嵌汇编指令
第十章 指针.
Struct結構 迴圈
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
C++ 程式設計 基礎篇 張啟中 Chang Chi-Chung.
第4章 汇编语言程序格式  汇编程序功能  伪操作  汇编语言程序格式  汇编语言程序的上机过程.
4-15 WDT HT66F50.
Holtek C Compiler V3--advanced
第1讲 C语言基础 要求: (1) C程序的组成 (2) C语言的标识符是如何定义的。 (3) C语言有哪些基本数据类型?各种基本数
Java變數 2014/6/24.
第 二 章 数据类型、运算符与表达式.
ARM Developer Suite 介 绍.
Oop8 function函式.
指標
4-9 Timer/Counter 控制七段速度
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第十四章 若干深入问题和C独有的特性 作业: 函数指针 函数作参数 函数副作用 运算 语句 位段 存储类别 编译预处理
C语言程序设计 李祥 QQ:
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
习题课 编译原理与技术 计算机科学与技术学院 李诚.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
4-12 外部中斷 HT66F70A.
第7章 程序的结构 四、生存期与存储属性 五、extern关键字与外部连接属性 六、static关键字与内部连接属性.
第二章 类型、对象、运算符和表达式.
第二章 基本数据类型 ——数据的表示.
Review 1~3.
挑戰C++程式語言 ──第9章 函數.
#include <iostream.h>
Introduction to the C Programming Language
第十二章 位运算.
单片机应用技术 (C语言版) 第4章 C51程序设计入门
變數、資料型態、運算子.
C/C++基礎程式設計班 C語言入門、變數、基本處理與輸入輸出 講師:林業峻 CSIE, NTU 3/7, 2015.
C++程序语言设计 Chapter 14: Templates.
Introduction to the C Programming Language
Presentation transcript:

合泰半导体股份有限公司 技术讲座 - Holtek V3 C Compiler介绍 主讲人:王幼端 2017/06/15

前言 C语言已成为单片机程序开发的主要语言 C语言的效率普遍低于汇编语言 Holtek开发V3 C编译程序,具有强大的优化功能 编译程序由GNU C(GCC) V4.8.2移植 GCC默认使用GNU89 C标准 GNU89 = The 1990 C standard plus GNU extensions 本课程基于HT-IDE3000 V7.94及Holtek C Compiler V3.52编写

Holtek V3 C与各家编译器效率对比 评比结果 (数值越高,效率越高)

Holtek V3 C与Holtek旧版编译器对比 Holtek V2/V1转V3的实际案例 客户/MCU信息 旧版code size V3 code size 北京客户 HT56RB27(V2) ROM : 48K ROM : 40% RAM bank0 overflow ROM : 33% RAM bank0 : 剩余44byte 欧洲客户 HT66F017(V1) ROM : 2K ROM : 81% ROM : 72% USB FW程序 HT82K95A(V2) ROM : 4K ROM : 95% ROM : 65%

概述 语法介绍 编译器优化介绍 常见问题解决方式 参考文档 与标准C的语法区别 扩展及语法功能 自带的优化功能 实际优化案例 如何写出更有效率的代码 常见问题解决方式 参考文档

语法介绍

Holtek V3 C 与标准C的语法区别 V3 C不支援的标准C语法 功能差异 函数指针 (function pointer) 递归函数 (recursion) : V3不支持递归调用 (除了尾递归,编译器可以将它 优化成非递归函数) V3 C Compiler暂不支持MP只有7bit的MCU及特定MCU (HT45F39及HT45F391) 功能差异 V3支持部分的标准函数库 (string.h, math.h…) ,但不支持stdio.h (详见《Holtek C标准函数库使用手册》) 数据类型差异 V3 标准C float 3byte 4byte double 8byte

扩展语法及功能(1/14) V3代码生成器 选项路径: 工具 - V3代码生成器

扩展语法及功能(2/14) 中断服务程序 语法 范例 void __attribute__((interrupt(vector))) ISR_name (void) { } volatile unsigned char TM_5ms = 0; void __attribute__((interrupt(0x14))) ISR_STM (void) { TM_5ms ++; _t2af = 0; }

扩展语法及功能(3/14) 中断服务程序注意事项 既可以被中断服务程序访问,也可以被其他函数访问的全局变量应定义为volatile 中断入口会自动保存寄存器 (ACC, BP, STATUS, MP/TBLP…),并在中断出口时恢复 中断可以调用子函数 若中断与主程序调用同一个子函数(linker报出warning),需保证在执行这个子函数时不会进入中断,否则会导致执行错误

扩展语法及功能(4/14) 绝对地址变量 语法 范例 static volatile var_type vname __attribute__((at(addr))); static volatile unsigned char num1 __attribute__ ((at(0x180))); static volatile unsigned char tab[3] __attribute__((at(0x280)));

扩展语法及功能(5/14) 绝对地址变量注意事项 volatile用来修饰被不同程序访问和修改的变量 (比如同时被主程序和中断服务程序使用) 编译器会将之翻译成组合语言的EQU指令,如下: 绝对地址变量的作用域为本文档,需定义成static static volatile unsigned char num1 __attribute__((at(0x180)));  num1 EQU [0180H]

扩展语法及功能(6/14) 定义const变量的地址 语法 范例 const ctype __attribute__ ((at(addr)))  cname = number; const unsigned char __attribute__((at(0x700)))  tab1[3]= {1,2,3};

扩展语法及功能(7/14) const变量的地址注意事项 需勾选以下参数才能使用 (路径 : 选项—工程设置—工程编译选项)

扩展语法及功能(8/14) 定义位变量 值只有0或1的变量可以定义成bit,占用1bit size,更节省空间 注意 : 全局的bit变量默认初始化,若不想初始化,可在工程设置中定义宏 : Disable_Bit_Initial V3.5 V3.4及之前的版本 bit flag1; bit flag2; typedef struct { unsigned char bit0 : 1; unsigned char bit1 : 1; unsigned char bit2 : 1; unsigned char bit3 : 1; unsigned char bit4 : 1; unsigned char bit5 : 1; unsigned char bit6 : 1; unsigned char bit7 : 1; }bit_type; bit_type bit_var; #define flag1 bit_var.bit0 #define flag2 bit_var.bit1

扩展语法及功能(9/14) 位变量注意事项 bit变量占用一个bit,仅最低位有效 bit变量不支持struct/union/const/register/array/pointer/函数参数及返回值 可指定bit变量的地址,语法如下: 范例 static volatile __attribute__((at(addr),bitoffset(val))) bit flag_name; static volatile __attribute__((at(0x18),bitoffset(0))) bit pa0; //表示pa0占用[18h].0的地址

扩展语法及功能(10/14) 内嵌汇编语言 语法 范例 说明 : compiler直接输出string字符串,可写在函数外,也可写在函数体内 asm(“string”); extern void FUN() ; asm(“extern _FUN_PAR1:byte”); //外部函式参数的声明 void main( ) { asm(“mov a,1”); asm(“mov _FUN_PAR1,a”); asm(“call _FUN”); //函数调用 }

扩展语法及功能(11/14) 指定函数的地址 语法 范例 中断函数也可以指定地址 : __attribute__((interrupt(vector),at(addr))) Re_type __attribute__((at(addr))) func (par1,par2) { } unsigned char __attribute__((at(0x700))) delay (unsigned int x) { }

扩展语法及功能(12/14) 支持硬件乘除法器 (MDU) 对具有乘除法寄存器的MCU,比如 : 个人医疗MCU BH66F2xx0/BH67F2xx0, V3.5 C compiler可利用MCU的硬件乘除法器,完成乘除法运算 以下是效益对比 :   乘除法运算库 MDU ROM Size (word) 运行时间 (最坏情况下的指令周期) 8bitх8bit 10 106 15 25 8bit / 8bit 133 16bitх16bit 19 289 29 16bit / 16bit 37 330 32bitх32bit 31 895 ─ 32bit / 32bit 67 1160 32bit / 16bit

扩展语法及功能(13/14) 硬件乘除法器 (MDU) 注意事项 大部分MCU的MDU都为16bit,所以对于char/unsigned char类型的乘除法运算,若使用MDU功能,使用的code size不一定更少,但运算速度会更快 不是所有的乘除法运算都会使用MDU运算 乘 long U long int U int char U char ─ MDU 除 long U long int U int char U char ─ MDU

少数ROM宽度<16位或者无TBHP的MCU 扩展语法及功能(14/14) 变量初始化 全局变量的初始化用startup code来实现,在main执行前完成初始化动作 (选项路径 : 选项→工程设置→编译选项→连接选项) 大部份MCU 少数ROM宽度<16位或者无TBHP的MCU 无勾选参数 startup1_l.asm startup1.asm 有勾选参数 startup0_l.asm startup0.asm

编译器优化介绍

编译器优化介绍 详见《Holtek C Compiler V3使用手册》 是否影 响调试 节省 ROM 节省RAM 节省 Stack 代数转换 (Algebraic Transformations) √ ● 复制传递 (Copy Propagation/Value Propagation) 删除执行不到的代码 (Unreachable code Elimination) 删除死代码 (Dead-code Elimination) 常量折迭 (Constant Folding) 常量传播 (Constant Propagation) 内联程序 (Inline Procedure) 强度削减 (Strength Reduction) 尾递归调用 (Tail Recursive Call) 子表达式删除 (Subexpression Elimination) 尾部合并 (Tail Merging) Bp 优化 Dead Section 删除

实际优化案例 优化案例 客戶/MCU信息 优化前 Code Size 优化后Code Size 南京客戶 HT45F67 ROM : 32K 北京客戶 HT69F50A ROM : 8K ROM : 81% ROM : 62% 台中客户 HT67F5650 ROM : 8K (长指令) ROM : 91% ROM : 83% 杭州客户 HT66F018 ROM : 4K ROM编译 Overflow ROM : 76%

如何写出更有效率的代码(1/8) 优化选项设置 (选项路径 : 选项 → 工程设置 → 编译选项) 编译设置 连接选项 优化生成的代码 (最优空间) 存取const变量时使用查表指令进行优化 连接选项 优化RAM空间 (不允许中断嵌套) 优化全局变量分配

如何写出更有效率的代码(2/8) 变量声明unsigned/singed 数据形态

如何写出更有效率的代码(3/8) 浮点常量

如何写出更有效率的代码(4/8) const数组

如何写出更有效率的代码(5/8) 循环替代

如何写出更有效率的代码(6/8) 封装频繁使用的代码为函数

如何写出更有效率的代码(7/8) 全局变量的分配

如何写出更有效率的代码(8/8) 中断服务程序 全局变量初始化 在中断里面实现的功能尽量少 减少复杂运算的使用 编译器调用startup函数为全局变量初始化,占用几十个word,如果需要 初始化的全局变量不多,可自己于函数中赋值

常见问题解决方式

常见问题解决方式(1/8) 编译器报的信息 Warning: variable 'temp' set but not used 这部分error/warning网站上都能查到大部分意思与解决方式 Internal compiler error… 编译器内部错误,请与Holtek反馈 Warning(L3008) : Same sub function exists between ISR(08H) CMG and ISR(04H) CMG: _func1 中断跟主函数或另一个中断调用同一个子函数func1 Error (L1038) "RAM (bank0) overflow, memory allocation fails for section …." RAM bank0溢出,可将全局变数用指定地址的方式定义至其它RAM bank

常见问题解决方式(2/8) 启用V3优化参数后,无法在Watch Window查看某些local变量数值? 因启用优化参数,变量有可能被优化,故无法查看 若要在debug时观察变量值,可以将此变量暂时定义为volatile, debug 结束后再删去,比如 : volatile int i,j,k; 中断访问的全局变量,此变量的相关语句被优化掉导致执行错误? 中断与主函数共同访问的全局变量需用volatile修饰

常见问题解决方式(3/8) 使用V3 compiler, debug时部分语句无法设置断点? 通常此类语句因无意义而被删除,如下line 4 因尾部合并进入错误的分支语句

常见问题解决方式(4/8) 使用V3 compiler,用于延时的循环代码被优化,怎么解决? 将变量定义成volatile,或使用内建延时函数GCC_DELAY (x),其中x为 unsigned int型常量

常见问题解决方式(5/8) 如何修改const变量的值? 比如,使用IAP把ROM的400H~410H值改写,执行temp=array[7]; temp值仍 为7 解决方式:把array[ ]定义在与temp = array[7];不同的C file __attribute__((at(0x400))) const unsigned char array[] = {0,1,2,3,4,5,6,7};

常见问题解决方式(6/8) 混合语言编程注意事项 使用长指令MCU,在C文件中定义全局变量若有在ASM文件中使用,需指 定地址或bank数 使用ASM写中断函数,应注意保存使用到的寄存器,特别是用到查表时,要 保存与恢复TBLH 具有多个ROM bank的MCU,在ASM文件中call function,应注意ROM BP的 设置与恢复,避免程序跑飞,如下 :

常见问题解决方式(7/8) 内嵌汇编的使用注意事项 汇编中使用的变量、函数、寄存器、标志位应符合汇编文件的定义 如果全局变量/函数在本文件中只在内嵌汇编中使用,应增加汇编的声明 : 寄存器/标志位应先定义后使用,可include INC文件,比如 : 内嵌汇编语言中的名字有区分大小写 asm(“extern _a:byte”); asm(“extern _func:near”); void main() { asm(“clr _a”); asm(“call _func”); } asm(“#include HT66F60.INC”); void main() { asm(“clr ACC”); asm(“clr C”); }

常见问题解决方式(8/8) 不要用汇编的思维写C程序,避免直接使用寄存器/标志位赋值,比如 : _mp1l = 0x80; _mp1h = 1; _iar1 = array[i]; 代替方案 : 定义变量var在地址0x180, var = array[i]; data <<= 1; if(_c) {…} 代替方案 : 直接判断data的最高位if (data&0x80) 编译程序用到的 特殊寄存器 主要用途 MP/IR 用于存取RAM space的值,搭配RAM BP使用,用于查表 BP RAM BP用于存取RAM space的值,ROM BP用于call function STATUS 用于表达式计算 TBLP 用于查表,用于存储RAM BP TBHP 用于查表 TBLH ACC 存储函数返回值等 PCL

参考文档 《HT-IDE3000使用手册》 《Holtek C Compiler V3使用手册》 《Holtek标准函数库使用手册》 介绍IDE, assembler, linker等tool的使用,在HT-IDE3000安装档DOC目录下 《Holtek C Compiler V3使用手册》 介绍Holtek C Compiler V3的使用,在HT-IDE3000安装档DOC目录下 《Holtek标准函数库使用手册》 介绍Holtek C支持的标准函数及使用方式,在HT-IDE3000安装档DOC目录下 《Holtek C Compiler V3 FAQ》 C Compiler V3的常见问题,在HT-IDE3000安装档DOC目录下 《gcc manual》 GCC使用手册下载网址http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc.pdf

问题与讨论 Q & A