250 likes | 413 Views
第七部分. ADSP-21xx 系列 DSP 的程序编制. A:ADSP-21xx 系列 DSP 的编程模型. ADSP-21xx 编程模型综述. 从程序编制的角度分析, ADSP-21xx 系列 DSP 包括三种运算部件( ALU、MAC、Shifter)、 两个数据地址产生器( DAGs)、 一个程序定序器和相关的标准外设接口及内部存储器。几乎所有的操作都要用到这些结构单元以及用于存储数据、指示操作模式或用做堆栈指针的寄存器。
E N D
第七部分 ADSP-21xx系列DSP的程序编制
ADSP-21xx编程模型综述 • 从程序编制的角度分析, ADSP-21xx系列DSP包括三种运算部件(ALU、MAC、Shifter)、两个数据地址产生器(DAGs)、一个程序定序器和相关的标准外设接口及内部存储器。几乎所有的操作都要用到这些结构单元以及用于存储数据、指示操作模式或用做堆栈指针的寄存器。 • 片内寄存器用于保存数据和地址以及控制和状态信息。有两种方式对寄存器进行访问。一种是直接在汇编指令中以寄存器名字来访问,另一种要以存储器地址来访问,这主要包括系统控制寄存器、等待状态控制寄存器、定时控制寄存器和串行通信接口控制寄存器等。
数据地址产生器(DAG1/DAG2) —— 数据地址产生器DAG1 和DAG2 每个都有12个14-bit 寄存器: 4个索引寄存器(I)用于存储数据指针,4个更改寄存器(M)用于更新数据指针,4个长度寄存器用于设置循环缓冲存储空间。DAG1 只能对数据存储器进行存取操作,但其输出具有位反序功能,DAG2可以对程序或数据存储器进行操作,除了存取数据外,DAG2还可以提供间接分支转移(jumps和calls)指令的目的地址。
程序定序器 —— 与程序定序器有关的寄存器控制子程序、循环程序以及中断及其服务程序的执行。它们包括指示有关状态和操作选定模式的寄存器。
运算单元 • —— 运算单元中的寄存器用于存储运算数据。 • 对于大多数操作,ALU和MAC需要两个输入数据。AX0、AX1和MX0、MX1寄存器存储X输入端的数据,AY0、AY1和MY0、MY1寄存器保存Y输入端的数据。, • AR和AF寄存器存储ALU的运算结果。AF中的内容可以反馈到ALU的Y输入端,而AR的内容可以提供给任意一个运算部件的X输入端。同样,MR0,MR1和MF寄存器存储MAC的运算结果并且可以反馈回输入端供下次运算使用。16-bit的MR0和MR1寄存器与8-bit的MR2寄存器结合在一起可以存储40-bit的乘/累加运算结果 • 移位器可以从ALU、MAC及自己的结果寄存器中获得输入数据,或是从特定的移位输入(SI)寄存器中获得输入数据。移位的结果可以存储在SR0和SR1寄存器中。SB寄存器存储块浮点运算中的块指数。SE寄存器则存储浮点数规格化/去规格化所需的移位次数值。 • 所有运算部件的寄存器都具有相应的一套后备寄存器。
PMD和DMD的数据交换单元 —— PX寄存器的宽度是8-bit ,它允许在16-bit的DMD总线与24-bit的PMD总线之间进行数据传输。在程序存储器与一个16-bit寄存器的数据传输中,PX提供或接收低8位的数据。
定时器 TPERIOD、TCONUNT和TSCALE寄存器保存定时器的定时中断重载数值(定时周期),递减计数器当前值和8位定标计数值。这几个寄存器是存储器地址映射的,其地址是:0x3FFD, 0x3FFC和 0x3FFB
串行通信接口 —— SPORT0和SPORT1每个都有接收(RX)、发射(TX)和控制寄存器。 控制寄存器均是存储器映射的,地址位于数据存储器的0x3FEF–0x3FFA处。 —— SPORT0还有控制其多通道功能的寄存器。 —— 每一个SPORT口控制寄存器具有控制帧同步、压扩方式和数据长度的控制位。 —— SCLKDIV寄存器确定内部产生的串行通信时钟的频率。 —— RFSDIV寄存器则决定内部生成的帧同步信号的速率。 —— 自适应缓冲寄存器则控制通信接口的自适应缓冲区特性。 —— 对SPORT接口的编程包括设置其控制寄存器,并且根据所选择的工作模式,设置相应的SCLKDIV和/或RFSDIV寄存器。
存储器接口和串行通信接口使能 —— 系统控制寄存器,映射在数据存储器地址DM(0x3FFF) 处,包括SPORT使能和SPORT1配置选择。对于除ADSP-2181以外的所有ADSP-21xx DSP芯片,该寄存器还包括控制其引导程序操作的字段:选择程序页面、指示程序存储器的等待周期等。系统控制寄存器还包括PWAIT字段用以指示对外部程序存储器进行操作时需要查入的等待状态数。 —— 等待状态控制寄存器,映射在数据存储器地址DM(0x3FFE) 处,包含对外部数据存储器进行存取操作需要查入的等待状态数。对于ADSP-2181,它还指示对I/O存储空间进行存取操作需要查入的等待状态数。
DSP的C语言程序 • 为什么要使用C语言? • 程序易于编写 • 程序的可读性好 • 可维护性好 • 采用C语言进行DSP程序编制的不足是什么? • 代码效率低下 • 编译后代码长度大,执行的周期长 • 中断处理过程复杂,响应速度慢 • 比较好的DSP程序开发方法 — 采用汇编语言与C语言混合的程序设计方法
ADSP-21xx的C语言编译器 • 完全兼容ANSI(美国国家标准化组织)C • 包括ANSI标准的C语言库函数以及多种DSP函数 • 支持与汇编语言源程序的接口 • 支持汇编语言直接嵌入C语言程序行中 • 支持为适应ADSP-21xx硬件体系结构的C语言功能扩展 • 可以在C语言与汇编语言混合编程的源程序级进行调试
C 语言编译器与集成调试环境( IDE) • 如果在项目中存在C语言源程序(*.c),C语言编译器将会自动启动运行 • C语言编译器在“项目属性定义页面”中的“Compile”属性页进行配置
C语言运行头文件 • C语言运行头文件的功能如下: • 设置中断向量表 • 初试化C语言的运行环境 • 使程序从DSP程序存储器PM的0x0000开始执行 • 设置DSP内部各个相关寄存器的缺省值 • 初始化堆栈及程序中的数据堆 • 不同型号DSP芯片的运行头文件是不同的
运行堆栈和运行数据堆 • 堆栈和运行数据堆均置于数据存储器(DM)中 • 链接描述文件(*.LDF)必须定义堆栈和数据堆在存储器中占用的空间
C 语言运行堆栈 • 为堆栈缓冲区所保留的数据存储器空间用堆栈指针和数据帧指针进行管理 • I4 = 堆栈指针 • M4 = 数据帧指针 • 缺省的堆栈空间大小为:2016字 – 程序编制人员可以通过更改LDF中的相关内容对该空间的大小重新定义 • 堆栈可以用于: • 在子程序之间传递数据 • 存储中间变量 • 存储函数调用的返回地址
C语言编译器的LDF MEMORY { seg_inttab { TYPE(PM RAM) START(0x00000) END(0x0002f) WIDTH(24) } seg_code { TYPE(PM RAM) START(0x00030) END(0x037ff) WIDTH(24) } seg_data2 { TYPE(PM RAM) START(0x03800) END(0x03fff) WIDTH(24) } seg_data1 { TYPE(DM RAM) START(0x00000) END(0x02fff) WIDTH(16) } seg_heap { TYPE(DM RAM) START(0x03000) END(0x037ff) WIDTH(16) } seg_stack { TYPE(DM RAM) START(0x03800) END(0x03fdf) WIDTH(16) } } 必须为运行堆栈和运行数据堆在数据存储器空间中进行定义
C语言编译器的LDF • LDF返回用于描述堆栈(向下生长)的常量 • ldf_stack_limit = lowest address in the stack • ldf_stack_base = highest address in the stack • 用于定义堆栈常量的LDF 代码 • 置于LDF的SECTIONS字段中 sec_stack { ldf_stack_limit = .; ldf_stack_base = . + MEMORY_SIZEOF(seg_stack) - 1; } >seg_stack • LDF将返回供218x_hdr.asm文件使用的堆栈常量 • 218x_hdr.asm 用于初始化运行堆栈
C 语言运行数据堆 • 为运行数据堆缓冲区所保留的数据存储器空间是用于可重定位动态存储空间的 • 缺省的堆栈空间大小为:2048字 – 程序编制人员可以通过更改LDF中的相关内容对该空间的大小重新定义 • 每当C语言程序调用Malloy( )函数时,就要用到运行数据堆 • 在LDF的SECTIONS字段中定义运行数据堆 sec_heap { .heap = .; .heap_size = MEMORY_SIZEOF(seg_heap); .heap_end = . + MEMORY_SIZEOF(seg_heap) - 1; } >seg_heap
C 语言编译器中寄存器的使用 • C语言编译器对于21xxDSP中某些特定寄存器只使用固定值 • 寄存器必须初试化 • 清为0: L0, L1, L2, L3, L4, L5, L6, L7, M2, M6 • 置为1: M7 • 受保护的寄存器:当寄存器被用到时必须先保存起来,用完后恢复 • I2, I3, I7,M0, M2, M4 • C语言运行堆栈寄存器用于堆栈的管理 : 不允许改变 • I4=Stack Pointer, M4=Frame Pointer • L4=0, M1=1 • 用于通用目的的Scratch寄存器 : 使用前不需要保存. • AX0, AX1, AY0, AR, AF, MX0, MX1, MY0, MY1, MR0, MF, SE, SI, SR0 • I0, I1, M3, I6, M5
对 ANSI C的功能扩充 • PM, DM 数据类型 int pm coefs /* 将数据存入程序存储器空间中 */ int data_buf /* 数据存储器DM是缺省的数据存储空间 */ • ASM( ) 用于将汇编指令嵌入C语言程序代码中 asm(“.var/dm buffer[10];”); asm(“idle;”); • VOLATILE关键字禁止C语言编译器重新定位、删除或合并用户编写的汇编指令或变量声明 volatile int x; All asm() instructions are volatile
在C语言程序中处理中断 • 必须包含 signal.h 头文件 • 中断函数 • signal(): ANSI标准函数 • 允许定义一个指定的中断源 • 为该中断源指定一个中断服务程序(ISR) • interrupt(): ANSI C的扩充函数 • 使能一个指定的中断源 • 为该中断源指定一个中断服务程序(ISR) • clear_interrupt() : ANSI C的扩充函数 • 使用 IFC控制寄存器清除一个指定的中断