您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 酒店餐饮 > DSP学习记录(存储器与中断)
//第一章EMIF的控制//07.09.06昨天发工资了。//sdram.prj向sdram中写数再读数,之后灯闪烁。//csl库:csl.h/csl_irq.h/csl_chip.h/csl_emifa.h1.烧写Flash改动想要学习烧写flash,于是把程序改成闪烁。while(1){for(i=0;i0x100000;i++){for(j=0;j40;j++){asm(Nop);}}*LED=(~(*LED))&0x03;}A)直接写到内部RAM中去通过LoadProgram就行了,不过要注意的是,在线修改程序后,一定要把正在运行着的程序停掉之后重新LoadProgram,那个ReLoadProgram好像不太好使。另外,板子上的复位键是用来复位板子的,复位之后,Ram中的程序还是以前那个,于重新下载没有任何帮助。在程序运行阶段,不要对板子突然停电,这样的话,又要重新启动CCS;也不要在板子停电之后运行程序,不然程序铁定死在那里。B)烧写到flash中去。B1)使用FlashBurn参见文档《烧写步骤》。z经验:1.flashBurn装不上很有可能是因为以前CCS3.1没有删干净,如果那样,只好重装系统。2.最后一步programmemory如果报错,那么reset一下就可以下载了,不用downloadfbtc,也不用erasememory,不过作了也没什么影响。z在烧写过程中有三个文件需要自己编写,分别是:C641x_SDRAM.cmd,Boot.asm,load_sdram.cmd在编译源程序时,Cmd文件用来分配rom和ram空间,告诉链接程序怎样计算地址和分配空间。Cmd文件由三部分组成:1.输入/输出定义:这一部分,可以通过ccs的“BuildOption........”菜单设置-lxx.lib连接系统文件xx.lib(rtsxx.lib包括ANSIC标准库、系统启动程序cint00、允许C访问特殊指令的函数和宏)(cslxx.lib)包括使用CSL库编程时的链接。在ccs文件夹下找,大端加e。-oxx.out最终生成的二进制文件命名为xx.out-mxx.map生成映射文件xx.mapCopyrightreservedyfgg-stack0xyyy系统堆栈为yyy字-c初始化romXx.obj链接目标文件2.MEMORY命令:描述系统实际的硬件资源MEMORY{PAGE0:name0[attr]:origin=constant,length=constantPAGEn:namen[attr]:origin=constant,length=constant}通常PAGE0对应rom;PAGE1对应ram。PAGE里包含的区间名字与其后面的参数反映了该区间的起始地址和长度。name:存储空间名称attr:存储空间属性:只读R,只写W,可包含可执行代码X,可以被初始化I。orgin:用来定义存储空间的起始地址Lenth:用来定义存储空间的长度3.SECTION命令:描述“段”如何定位SECTIONS{.SectionNameDistributeNamePAGENumber}系统保留的段名参见相关书籍。本例在boot.asm中声明.boot_load段,在C641x_SDRAM.cmd文件中将其放到了boot区内。在C源程序中,可以利用两个伪函数,将程序中声明的变量或函数放到数据/程序空间内。#pragmaCODE_SECTION(symbol.sectionname)程序空间#pragmaDATA_SECTION(symbol,sectionname)数据空间此外,配置DSP空间时,注意寄存器PMST中MP/MC,OVLY,DROM位。在使用hex6x命令将.out文件转换成16位.hex文件时,xx.cmd文件用作格式转换命令文件。转换后的十六进制格式文件即是引导表的内容,引导表包含并行引导的标识、程序执行的入口地址、程序存放的目的地址、用户程序及用户程序块长度。具体格式参见spru186.pdf第11章注意:1.注意器件接口、存储器接口和ROM接口三者关系同目标文件数量对应。2.使用SECTION命令指定需要转换的段,需要启动时载入的段。3.image模式产生连续的储存区域。4.建立引导表步骤:P255Bootorg指明boottable的地址。Bootsection指明bootroutine的起始地址。Boottable是数据搬移表,而bootroutine是引导程序,被用作引导dsp启动,当该程序执行完毕,程序跳转到-e指明的地址开始执行,若没有-e说明,程序跳转到Copyrightreservedyfggcoff定义的程序入口(boottable中)。如果MP/MC=1;则程序不自举,直接从0ff80h开始执行。Boot.asm文件:驻留在地址0处,程序从此处开始执行,作用为搬移代码和数据。C6x系列的dsp内部驻有自引导程序,会将flashrom中1k内容搬移到片内0地址开始的内存空间。如果代码、数据大于1k,那么就需要在这1k程序中将代码段和数据段复制到内存中运行。Boot.asm采用汇编编写,汇编语句格式:label:||[cond]instruction.unitoperand;commentlabel:代码或变量地址[cond]:条件寄存器instruction:助记符(mnemonic);伪指令(directive).unit:功能单元(可选)operand:寄存器;常量;指针。;comment:注释简要分析boot.asm文件:.titleFlashbootuputilityforseed-dec6416.optionD,T.length102.width140COPY_TABLE.equ0x64000400//使用.equ,使COPY_TABLE=0x64000400;在load_sdram.cmd文件中可以看出,//这个地址正是boottable的首地址。.sect.boot_load//声明boot_load段,以下代码嵌入该段中.global_boot//声明_boot符号,该符号可以在其他模块中被引用。_boot:zeroB1//将B1清零,B1为内置寄存器。_myloop:nop5//执行5次空操作,避免流水线冲突。_myloopend:nopmvklCOPY_TABLE,a3//将COPY_TABLE的值赋给A3内置寄存器mvkhCOPY_TABLE,a3//汇编语言不区分大小写ldw*a3++,b1//将引导表指示的程序入口地址给B1//地址以字节为单位,故a3实际是加4copy_section_top://引导表结构参见spru186p,P254ldw*a3++,b0//第一段数据个数,以byte为单位ldw*a3++,a4//第一段数据目标地址nop3[!b0]bcopy_done//如果数目为全零,跳转到结束nop5//转移指令有5周期延迟,故之后的5个语句都会进入流水线//相继执行,如果不想执行,nop5。copy_loop:ldb*a3++,b5//将8位数据放入b5Copyrightreservedyfggsubb0,1,b0//待拷贝数据量减一[b0]bcopy_loop//如果该段还有字段未拷贝,则继续拷贝[!b0]bcopy_section_top//该段转移完毕,跳转转移下一段zeroa1//a1清零[!b0]and3,a3,a1//该段转移完毕,将a3低两位赋给a1stbb5,*a4++//将b5的低八位放入a4[!b0]and-4,a3,a5//该段转移完毕,将a3的低2位置0赋给a5.[a1]add4,a5,a3//本句只有b0=0时方能执行,将a5加4赋给a3//后几句的意思连起来就是当开始一个新段时,如果a3低2位不为零,则将低2位清零进位,//即:引导表中段的起始位置是以32位(w)计算的。(此为猜测,待考,正确率80%)copy_done:b.S2b1//跳到程序入口nop52.外部地址空间分配EMIF分为四个CE空间,各自地址可以在datasheet查到。所以分派好储存器地址就可以不要管CE管脚的逻辑了,dsp会自动设置。CE空间通过几个寄存器进行配置,详情参见文档和程序。3.中断声明Vector.asm文件声明了中断向量,以后会对中断作单独的讨论,这里不再赘述。只是要注意带参数宏的声明方法。4.EMIF控制寄存器配置A)程序代码分析本程序基于CSL库建立,使用大量头文件和API函数,具体问题还木有搞清楚,留待以后吧。a)EMIFA_Config:自定义的一个包含12个32位数值的结构,其中的数值对应了EMIF控制寄存器对应的12个需要配置的寄存器的值。使用EMIFA_config(*EMIFA_Config)进行对寄存器的配置。b)EMIFA_config(*EMIFA_Config)函数:指定首地址和各个寄存器的偏移量,然后将参数值对应地付给各个寄存器。符号“\”为行连接符,表示下一行的内容同上一行是同一行的。“#”为宏转义符,将之后参数转义为字符串。“##”为宏合并符,将之后参数与之前的字符连接起来形成新的参数。Volatile关键字:提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。c)EMIFA_Config内部函数,均是调用CSL-API函数,对每一位移位与掩码。d)伪指令#pragmapragma就是为了让编译器编译出的C或C++程序与机器硬件和操作系统保持完全兼容而定义的宏扩展,#pragma是和特定编译器相关的。e)主函数中调用了很多中断函数IRQ_***(),尽快找本CSL的书来看看。参见文档TMS320C6000CSLAPIReferenceGuide.Pdf.CopyrightreservedyfggB)EMIF相关寄存器说明和配置方法。本例中,SDRAM使用了EMIFA的CE0空间,对应地址0x80000000-0x8fffffff,Flash使用EMIFB的CE1空间,对应地址为0x64000000-0x641fffff。代码中寄存器配置为GBLCTL;CE0~3CTL;SDCTL;SDTIM;SDEXT;CESEC0~3。对照程序,发现CSL编程有很大方便。详情参考emif.pdf/P135。5.LED灯的使用通过EMIFB的CE0空间外接CPLD译码控制。SDRAM程序的分析就到此为止。对SDRAM来说,这仅仅是些皮毛,比如SDRAM的各种方式,如自举刷新,时钟设置等等都没有深入的涉及。这些只有等到真正自己做板子的时候才会有动力去钻研了。对DSP的学习,那更是万里长征的第一步,欲知后事如何,且看第二章,中断。万恶的ccs居然不支持中文路径,再一次鄙视。Copyrightreservedyfgg//第二章中断//07.09.13天道酬勤//Timer.prj不想仿真。//csl库:csl.h/csl_timer.h/csl_irq.h/csl_emifb.h1.调试遇到的问题Timer这个程序编译的时候老是说can’topenobjectfile。网上说是空间分配的问题,可是我把段空间改大之后还是没有用,郁闷之下,只好重建一个目录。怎样包含头文件?a.用户不用addfile,ccs会根据文件包含情况自己将头文件加入include。b.在buildoption-compiler-preprocessor选项下,指定头文件的路径,否则文件里使用头文件里包含的变量会报错说没有定义。2.预备知识C编译器将C程序定义的所有标识符前都加一下划线(-)。因此,必须将在C程序中要引用的汇编变量和汇编模块子程序的名字前加上下划线(-)。如果变量仅在汇编模块中使用,则不加下划线(-)的变
本文标题:DSP学习记录(存储器与中断)
链接地址:https://www.777doc.com/doc-4714482 .html