CMD文件的编写
- 格式:docx
- 大小:44.50 KB
- 文档页数:24
Windows CMD命令行中的文本文件处理技巧Windows CMD命令行是Windows操作系统中的一个强大工具,它可以通过各种命令来执行各种任务。
其中,文本文件处理是CMD命令行中的一个重要功能。
本文将介绍一些在CMD命令行中处理文本文件的技巧,帮助读者更好地利用这个工具。
首先,我们来讨论如何在CMD命令行中创建、编辑和查看文本文件。
要创建一个文本文件,可以使用"echo"命令。
例如,输入"echo Hello World > text.txt",将会创建一个名为"text.txt"的文本文件,并将"Hello World"写入其中。
要编辑一个文本文件,可以使用"edit"命令或者"notepad"命令。
例如,输入"edit text.txt"将会用默认的文本编辑器打开"text.txt"文件。
要查看一个文本文件的内容,可以使用"type"命令。
例如,输入"type text.txt"将会在命令行中显示"text.txt"文件的内容。
接下来,我们来讨论如何在CMD命令行中对文本文件进行搜索和替换。
要在一个文本文件中搜索某个关键词,可以使用"find"命令。
例如,输入"find "Hello" text.txt"将会在"text.txt"文件中搜索包含"Hello"的行,并将其显示在命令行中。
要替换一个文本文件中的某个关键词,可以使用"replace"命令。
例如,输入"replace "Hello" "Hi" text.txt"将会将"text.txt"文件中所有的"Hello"替换为"Hi"。
cmd的c语言-回复如何使用C语言中的cmd命令进行文件操作在C语言中,我们可以使用cmd命令(也称为命令行)来进行文件操作。
通过这些命令,我们可以在程序中执行各种文件相关的操作,如创建、打开、读取、写入、删除等。
本文将一步一步地回答如何使用C语言中的cmd 命令进行文件操作。
首先,我们需要包含`<stdlib.h>`头文件来使用C语言中的cmd命令。
这个头文件提供了一些实用的函数,可以方便地执行cmd命令。
一、创建文件要创建文件,我们可以使用`system()`函数来执行cmd命令。
`system()`函数接受一个字符串作为参数,该字符串是要执行的cmd命令。
c#include <stdlib.h>int main(){system("type nul > file.txt");return 0;}上面的代码通过执行`type nul > file.txt`命令来创建了一个名为`file.txt`的空文件。
二、打开文件要打开文件,我们可以使用`system()`函数中的`start`命令来执行。
`start`命令可以打开指定的文件。
c#include <stdlib.h>int main(){system("start notepad.exe file.txt");return 0;}上面的代码通过执行`start notepad.exe file.txt`命令来打开以记事本编辑器打开`file.txt`文件。
三、读取文件要读取文件,我们可以使用`system()`函数中的`type`命令来执行。
`type`命令可以显示指定文件的内容。
c#include <stdlib.h>int main(){system("type file.txt");return 0;}上面的代码通过执行`type file.txt`命令来显示`file.txt`文件的内容。
高级Windows CMD命令脚本编写技巧和建议在日常工作和学习中,我们经常需要使用命令行来完成一些任务,而Windows CMD命令脚本编写技巧的掌握对于提高工作效率和简化操作流程至关重要。
本文将介绍一些高级的Windows CMD命令脚本编写技巧和建议,帮助读者更好地利用命令行工具。
一、变量的使用在编写CMD脚本时,变量的使用是非常重要的。
通过定义和使用变量,我们可以在脚本中存储和操作数据,实现更加灵活和可扩展的功能。
1. 定义变量:使用set命令可以定义和赋值变量。
例如,set name=John可以定义一个名为name的变量,并将其赋值为John。
2. 使用变量:在脚本中使用变量时,需要使用%变量名%的形式。
例如,echo %name%可以输出变量name的值。
3. 系统变量:除了自定义变量,CMD还提供了一些系统变量,如%USERNAME%表示当前登录用户的用户名,%DATE%表示当前日期,%TIME%表示当前时间等。
这些系统变量可以方便地在脚本中使用。
二、条件判断和循环条件判断和循环是CMD脚本中常用的控制结构,可以根据不同的条件执行不同的命令或重复执行某个命令。
1. 条件判断:使用if命令可以进行条件判断。
例如,if exist file.txt echo 文件存在可以判断当前目录下是否存在名为file.txt的文件,如果存在则输出“文件存在”。
2. 循环:使用for命令可以进行循环操作。
例如,for /l %%i in (1,1,10) doecho %%i可以输出从1到10的数字。
三、命令的重定向和管道命令的重定向和管道是CMD脚本中非常有用的功能,可以将命令的输出结果保存到文件中或将多个命令连接起来实现更复杂的操作。
1. 重定向:使用>符号可以将命令的输出结果重定向到文件中。
例如,dir > file.txt可以将当前目录的文件列表保存到名为file.txt的文件中。
28035cla 的cmd编写在计算机编程领域,CMD(Command Prompt)是一种强大的工具,可以用于执行各种操作系统命令。
对于很多人来说,CMD可能并不陌生,但是对于如何编写CMD程序,却可能相对陌生。
本文将介绍如何编写CMD程序,以及一些常见的编程技巧。
首先,要编写CMD程序,我们需要了解一些基本的CMD命令。
比如,dir命令可以列出当前目录下的所有文件和文件夹;cd命令可以进入到指定的目录;copy命令可以复制文件等等。
这些基本的CMD命令是我们编写CMD程序的基础。
其次,我们可以使用批处理文件(.bat文件)来编写CMD程序。
批处理文件是一种包含一系列CMD命令的文本文件,可以一次性执行多个CMD命令。
编写批处理文件的方法很简单,只需要在文本文件中逐行输入CMD命令即可。
比如,我们可以创建一个批处理文件,其中包含dir命令和copy命令,然后保存为test.bat,就可以通过双击test.bat文件来执行这些CMD命令。
除了使用批处理文件,我们还可以通过CMD脚本来编写CMD程序。
CMD脚本是一种文本文件,其中包含一系列CMD命令和控制流语句,可以实现更加复杂的逻辑。
通过CMD脚本,我们可以实现循环、条件判断、函数调用等功能。
编写CMD脚本的方法和编写批处理文件类似,只是需要在文本文件中添加更多的控制流语句。
在编写CMD程序时,我们还需要注意一些编程技巧。
比如,可以使用变量来存储临时数据;可以使用注释来解释代码的作用;可以使用错误处理机制来处理异常情况等等。
这些编程技巧可以帮助我们编写更加规范和易读的CMD程序。
总的来说,编写CMD程序并不是一件困难的事情,只要掌握了基本的CMD命令和编程技巧,就可以轻松地编写出各种功能强大的CMD程序。
希望本文的介绍对大家有所帮助,让大家更加熟练地运用CMD工具,提高工作效率。
28035cla 的cmd编写CMD(Command Prompt)是Windows操作系统中的命令行工具,用户可以在CMD中通过输入特定的命令来执行各种操作。
在本文中,我将逐步指导您如何编写一个名为"28035cla"的CMD程序。
第一步:创建CMD文件首先,您需要在计算机上创建一个CMD文件。
CMD文件是以.bat或.cmd 为扩展名的文本文件,它包含一系列CMD命令。
您可以使用任何文本编辑器(如记事本)来创建CMD文件。
在命名“28035cla.cmd”后,您可以双击打开这个文件并编辑。
第二步:添加必要的命令接下来,我们将根据需求添加必要的命令。
根据[28035cla]这个主题,我们假设您想编写一个CMD程序来执行数学计算。
首先,在CMD文件中添加一个欢迎消息,用于与用户进行交互。
输入以下命令:echo 欢迎使用28035cla数学计算程序!以上代码将关闭命令行的回显功能,并显示一条欢迎消息。
接下来,我们将使用以下命令提示用户输入两个数字,并将其存储到变量中:set /p num1=请输入第一个数字:set /p num2=请输入第二个数字:以上代码将提示用户输入两个数字,并将第一个数字存储在名为"num1"的变量中,将第二个数字存储在名为"num2"的变量中。
第三步:执行数学计算现在,我们可以使用变量中存储的数字执行数学计算并输出结果。
以下是一些基本的数学计算示例:set /a result=num1 + num2echo 结果:result以上代码将使用"/a"参数进行计算,并将结果存储在名为"result"的变量中。
然后,通过使用"echo"命令输出结果。
2. 减法:set /a result=num1 - num2echo 结果:result以上代码将两个数字相减,并将结果存储在"result"中,然后输出结果。
Windows CMD命令中的文本编辑技巧在日常使用Windows操作系统时,CMD命令行是一个非常有用的工具。
除了执行各种系统命令外,CMD还提供了一些文本编辑的功能,方便用户对文本文件进行修改和处理。
本文将介绍一些常用的CMD文本编辑技巧,帮助读者更高效地进行文本编辑。
1. 查找和替换在CMD命令行中,我们可以使用findstr命令来查找文本文件中的特定内容。
例如,要查找一个文本文件中包含关键词"Windows"的所有行,可以使用以下命令:findstr "Windows" filename.txt如果要查找多个关键词,可以使用正则表达式进行模式匹配。
例如,要查找包含"Windows"或"CMD"关键词的行,可以使用以下命令:findstr "Windows|CMD" filename.txt另外,CMD还提供了replace命令来替换文本文件中的内容。
例如,要将文本文件中所有的"Windows"替换为"Linux",可以使用以下命令:replace "Windows" "Linux" filename.txt2. 删除重复行有时候我们需要对文本文件进行去重操作,即删除重复的行。
CMD命令行提供了一个非常简单的方法来实现这个功能。
只需使用sort命令对文本文件进行排序,然后使用unique命令删除重复行。
以下是具体的操作步骤:sort filename.txt | unique > output.txt这个命令会将filename.txt文件中的内容进行排序,并将结果输出到output.txt文件中。
重复的行会被自动删除,只保留唯一的行。
3. 合并和拆分文件有时候我们需要将多个文本文件合并成一个文件,或者将一个大文件拆分成多个小文件。
DSP2812学习笔记-CMD⽂件编写⾸先我们要知道什么是CMD⽂件,它是⽤来⼲什么的,然后再来看看它有些什么,怎么去编写⼀个CMD⽂件。
CMD即command命令,命令⽂件指定存储区域的分配。
由于 DSP281X 系列的独特性(⽚内存在 SRAM 和 FLASH)所以必须创建⼀个⽤户链接命令⽂件,以便在运⾏程序时,每个块都能对号⼊座。
2812中CMD 采⽤的是分页制,其中PAGE0⽤于存放程序空间,⽽PAGE1⽤于存放数据空间。
我们结合SRAM.cmd(附件1)⽂件来介绍下CMD⽂件的编写。
CMD的伪指令:MEMORY 和 SECTIONS 是命令⽂件中最常⽤的两伪指令。
MEMORY伪指令⽤来表⽰实际存在⽬标系统中的可以使⽤的存储器范围,在这⾥每个存储器都有⾃⼰的名字,起始地址和长度。
SECTIONS伪指令是⽤来描述输⼊端是如何组合到输出端内的。
CMD ⽂件⾥有两个基本的段:初始化段和⾮初始化段。
初始化段包含代码和常数等必须在 DSP 上电之后有效的数。
故初始化块必须保存在如⽚内 FLASH 等⾮遗失性存储器中。
在SRAM.cmd⽂件中已初始化的段:.text,.cinit,.const,.econst,..pinit 和.switch..每个⼩段⾥⾯存储的量说明如下:.text:所有可以执⾏的代码和常量.cinit:全局变量和静态变量的 C 初始化记录.const:包含字符串常量和初始化的全局变量和静态变量(由 const)的初始化和说明.econst:包含字符串常量和初始化的全局变量和静态变量(由 far const)的初始化和说明.pinit:全局构造器( C++)程序列表.switch:包含转换语⽓声明的列表⾮初始化段中含有在程序运⾏过程中才像变量内写数据进去,所以⾮初始化段必须链接到易失性存储器中如 RAM。
⾮初始化的段:.bss,.ebss,.stack,.sysmem,和 esysmem.(更好的理解就是,这些段就是存储空间⽽已)每个⼩段⾥⾯存储的量说明如下:.bss: 为全局变量和局部变量保留的空间,在程序上电时,cinit 空间中的数据复制出来并存储在.bss 空间中。
cmd写法Command Prompt(命令提示符)是Windows操作系统中的一个命令行工具,允许用户通过键入命令来执行各种操作。
以下是关于CMD 写法的详细解释,包括一些基本的CMD命令和其用法。
1. 基本CMD命令1.1 dirdir 命令用于列出当前目录中的文件和子目录。
dir1.2 cdcd 命令用于更改当前目录。
cd[目录路径]1.3 copycopy 命令用于复制文件。
copy[源文件路径] [目标文件路径]1.4 deldel 命令用于删除文件。
del[文件路径]1.5 renren 命令用于重命名文件。
ren[旧文件名] [新文件名]2. 进阶CMD命令2.1 ipconfigipconfig 命令用于显示当前系统的网络配置信息。
ipconfig2.2 pingping 命令用于测试与另一台计算机的网络连接。
ping [目标IP地址或域名]2.3 systeminfosysteminfo 命令用于显示有关计算机系统的详细信息。
systeminfo2.4 tasklisttasklist 命令用于显示当前正在运行的进程列表。
tasklist2.5 taskkilltaskkill 命令用于终止或中止运行中的进程。
taskkill /F/IM[进程名称]3. CMD脚本编写你可以使用文本编辑器编写CMD脚本,以执行一系列命令。
@echo offecho Hello, CMD!diripconfigpause将上述脚本保存为.bat 文件,并双击运行即可。
4. CMD命令的输出重定向4.1 输出到文件dir>output.txt4.2 追加到文件ipconfig >>output.txt4.3 从文件中读取type input.txt5. CMD命令的管道dir|find"txt"上述命令将dir的输出通过管道传递给find命令,用于查找包含"txt" 的行。
TMS320F2812的CMD文件的编写经验总结CMD文件里包含三部分内容:1)输入/输出定义:.obj文件:链接器要链接的目标文件;.lib文件:链接器要链接的库文件;.map文件:链接器生成的交叉索引文件;.out文件:链接器生成的可执行代码;链接器选项2)MEMORY命令:描述系统实际的硬件资源3)SECTIONS命令:描述“段”如何定位F2812的CMD文件只包含后两部分,现对它的编写做一下总结:(一)用于调试时用,取名为SRAM.CMD这里有个比较标准的F2812的CMD文件,可以供大家借鉴使用:MEMORY{PAGE 0:ZONE0 : origin = 0x002000, length = 0x002000ZONE1 : origin = 0x004000, length = 0x002000RAML0 : origin = 0x008000, length = 0x001000ZONE2 : origin = 0x080000, length = 0x080000ZONE6 : origin = 0x100000, length = 0x080000OTP : origin = 0x3D7800, length = 0x000800FLASHJ : origin = 0x3D8000, length = 0x002000FLASHI : origin = 0x3DA000, length = 0x002000FLASHH : origin = 0x3DC000, length = 0x004000FLASHG : origin = 0x3E0000, length = 0x004000FLASHF : origin = 0x3E4000, length = 0x004000FLASHE : origin = 0x3E8000, length = 0x004000FLASHD : origin = 0x3EC000, length = 0x004000FLASHC : origin = 0x3F0000, length = 0x004000FLASHA : origin = 0x3F6000, length = 0x002000BEGIN_H0 : origin = 0x3F8000, length = 0x000002BEGIN_FLASH : origin = 0x3F7FF6, length = 0x000002PRAMH0 : origin = 0x3F8002, length = 0x001FFEZONE7 : origin = 0x3FC000, length = 0x003FC0ROM : origin = 0x3FF000, length = 0x000FC0 // boot ROM available if MP/MCn=0 RESET : origin = 0x3FFFC0, length = 0x000002VECTORS : origin = 0x3FFFC2, length = 0x00003EPAGE 1 : // Data MemoryRAMM0 : origin = 0x000000, length = 0x000400RAMM1 : origin = 0x000400, length = 0x000400DEV_EMU : origin = 0x000880, length = 0x000180FLASH_REGS : origin = 0x000A80, length = 0x000060CSM : origin = 0x000AE0, length = 0x000010XINTF : origin = 0x000B20, length = 0x000020CPU_TIMER0 : origin = 0x000C00, length = 0x000008PIE_CTRL : origin = 0x000CE0, length = 0x000020PIE_VECT : origin = 0x000D00, length = 0x000100ECAN_A : origin = 0x006000, length = 0x000100ECAN_AMBOX : origin = 0x006100, length = 0x000100SYSTEM : origin = 0x007010, length = 0x000020SPI_A : origin = 0x007040, length = 0x000010SCI_A : origin = 0x007050, length = 0x000010XINTRUPT : origin = 0x007070, length = 0x000010GPIOMUX : origin = 0x0070C0, length = 0x000020GPIODAT : origin = 0x0070E0, length = 0x000020ADC : origin = 0x007100, length = 0x000020EV_A : origin = 0x007400, length = 0x000040EV_B : origin = 0x007500, length = 0x000040SCI_B : origin = 0x007750, length = 0x000010MCBSP_A : origin = 0x007800, length = 0x000040RAML1 : origin = 0x009000, length = 0x001000FLASHB : origin = 0x3F4000, length = 0x002000CSM_PWL : origin = 0x3F7FF8, length = 0x000008DRAMH0 : origin = 0x3f9000, length = 0x001000}SECTIONS{// Compiler Required Sections.text : > PRAMH0, PAGE = 0.cinit : > PRAMH0, PAGE = 0.stack : > RAMM1, PAGE = 1.bss : > RAMM0, PAGE = 1.ebss : > RAMM0, PAGE = 1.const : > RAMM0, PAGE = 1.econst : > RAMM0, PAGE = 1.sysmem : > RAMM1, PAGE = 1.reset : > RESET, PAGE = 0, TYPE = DSECT // we are not using the .reset // section//Peripheral Frame 0 Register StructuresDevEmuRegsFile : > DEV_EMU, PAGE = 1FlashRegsFile : > FLASH_REGS, PAGE = 1CsmRegsFile : > CSM, PAGE = 1XintfRegsFile : > XINTF, PAGE = 1CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1PieCtrlRegsFile : > PIE_CTRL, PAGE = 1PieVectTable : > PIE_VECT, PAGE = 1//Peripheral Frame 1 Register StructuresSysCtrlRegsFile : > SYSTEM, PAGE = 1SpiaRegsFile : > SPI_A, PAGE = 1SciaRegsFile : > SCI_A, PAGE = 1XIntruptRegsFile : > XINTRUPT, PAGE = 1GpioMuxRegsFile : > GPIOMUX, PAGE = 1GpioDataRegsFile : > GPIODAT PAGE = 1AdcRegsFile : > ADC, PAGE = 1EvaRegsFile : > EV_A, PAGE = 1EvbRegsFile : > EV_B, PAGE = 1ScibRegsFile : > SCI_B, PAGE = 1McbspaRegsFile : > MCBSP_A, PAGE = 1//Peripheral Frame 2 Register StructuresECanaRegsFile : > ECAN_A, PAGE = 1ECanaMboxesFile : > ECAN_AMBOX PAGE = 1//Code Security Password LocationsCsmPwlFile : > CSM_PWL, PAGE = 1}(二)用于烧写到FLASH中时用,取名为FLASH.CMDFLASH.CMD与SRAM.CMD基本一样,只是有两处改动:一是MEMORY中将你的程序代码部分映射到FLASH空间里;二是在SECTIONS中添加一个用户定义的起始段,起始段的代码如下://User Defined Sections , Used by file DSP28_CodeStartBranch.asmcodestart : > BEGIN, PAGE = 0其中DSP28_CodeStartBranch.asm中的关键代码为:.ref _c_int00.sect “codestart”Code_start:LB _c_int00.end(三)SECTIONS中段的含义与用户自定义段的方法1、各个段的含义以下是TI公司的技术文档中对一些段的说明,现截个图给大家参考:除此外还有一些段的含义如下(这仅是我见过的,有漏下的还请提示,大家一起学习):.reset 复位中断向量表.vectors 中断向量表.data 已初始化数据,常数数据(比如对变量的初始化数据).pvecs 外围模块中断向量表.ref 引用外部定义的变量或函数名.global 引用全局变量或函数.space 定义要保留的空间.def 定义变量,与#define功能相同.end 段的结束标识.sect 用户自定义的已初始化段.asect 比.sect多了绝对地址定位功能,一般不用.usect 用户自定义的未初始化段已初始化的段:.text, .cinit, .const, .econst, .pinit, .switch.text:所有可以执行的代码和常量.cinit:全局变量和静态变量的C初始化记录.const:包含字符串常量和初始化的全局变量和静态变量(由const)的初始化和说明.econst:包含字符串常量和初始化的全局变量和静态变量(由far const)的初始化和说明.pinit:全局构造器(C++)程序列表.switch:包含转换语气声明的列表非初始化的段:.bss, .ebss, .stack, .sysmem, .esysmem(更好的理解就是,这些段就是存储空间而已)..bss:为全局变量和局部变量保留的空间,在程序上电时,cinit空间中的数据复制出来并存储在.bss空间中.ebss:为使用大寄存器模式时的全局变量和静态变量预留的空间,在程序上电时,cinit空间中的数据复制出来并存储在.ebss中.stack:为系统堆栈保留的空间,主要用于和函数传递变量或为局部变量分配空间.sysmem:为动态存储分配保留的空间。
CMD文件的原理玄德(网名)于2009 年3 月一、前言开发TI 公司的DSP 芯片,肯定要编写或者修改CMD 文件,这是在单片机开发中没有碰到过的新事物,也是学习DSP的难点。
面对里面种类繁多、名称各异、来历不明、作用不清、功能千差万别的存储器、区域和变量、寄存器,初学者往往都会一头雾水。
甚至很多人已经把项目成功地完成了,对CMD文件仍然是一知半解。
笔者也经历了极度困惑的过程,曾经大量地看书,下载资料,分析所能搜集到的CMD源文件。
可惜的是,无论是TI 公司的原始文档,还是网上的资料,或者BBS的帖子,都没有透彻地说明CMD 文件的原理和使用,只说“然” ,要靠自己去体会“所以然” ,去“悟” 。
终于有一天,我悟到了,也许只是“一些” 。
现在,我把自己的“一些”写下来。
我将细致而通俗地说明CMD 文件的原理,给您“鱼” ,更给您“渔” ,一步步地引导象我当初一样的初学者。
我将以TI 的2407 为对象展开说明,对于TI 公司其他型号、其他系列的DSP,道理是完全相同的。
用时下学术界最最最流行的语式,叫做“基于2407”——这个词起源于英文的“based on” ,或“something based” ,被我们大量地引用,以至于令人反胃了——我们美妙、绚烂的语言,现在只剩下“基于”了。
笔者水平有限,但保证会用心去写,您会看到很多别处没有的思路和信息,相信会基本打通初学者的任督二脉。
本文适用于那些有单片机的开发基础、刚开始学习DSP 的初学者。
如果你还不知道程序空间,数据空间这些名词,可能就比较困难了。
二、CMD文件的起源在DSP系统中,存在大量的、各式各样的存储器,CMD文件所描述的,就是开发工程师对物理存储器的管理、分配和使用情况。
有必要先复习一下存储器的知识。
目前的物理存储器,种类繁多,原理、功能、参数、速度各不相同,有PROM、EPROM、EEPROM、FLASH、NAND FLASH、NOR FLASH等(ROM 类),还有SRAM、DRAM、SDRAM、DDR、DDR2、FIFO 等(RAM 类)。
无论多么复杂,从断电后保存数据的能力来看,只有两类:断电后仍然能够保存数据的叫做非易失性存储器(non-volatile,本文称为ROM 类),数据丢失的叫做易失性存储器(本文称为RAM 类);ROM 类的芯片都是非易失性的,而RAM 类都是易失性的。
即使同为ROM类或同为RAM 类存储器,仍然存在速度、读写方法、功耗、成本等诸多方面的差别。
比如SRAM 的读写速度,从过去的15ns、12ns,提高到现在的8ns、10ns,FLASH的读取速度从120ns、75ns,到现在的40ns、30ns。
有没有人这样想过:使用存储器的人,希望存在这样的区别吗?或者说,理想的存储器,应当是什么样的?…………我们使用存储器时,如果没有人为地改变它,就希望里面的数据永远不要变,即使断了电也要完好地保存;如果里面的内容是我不需要的或者不能用的,我自然就会给它写入有用的内容,比如初始化。
理想的存储器就应当永远保存数据,无论掉电与否,而且,希望读写速度为每秒无穷多字节,是0ns,而不是什么8ns,10ns。
——不是吗?然而,人类实现存储器芯片的技术,还没有达到理想情况,所以才会有这么多类别。
“非易失”和“速度”就是一对典型的矛盾。
非易失的ROM 类存储器,可以“永远”地保存数据,但读写速度却很低,比如30ns;RAM 的速度(8ns)一般都比ROM(30ns)快得多,但却不能掉电保存。
这是很无奈的现实。
假如有那么一天,ROM 类的读写速度和RAM 一样快,或者RAM 也可以掉电保存数据,就不存在易失和非易失的区别了,那将是革命性的进步。
那时,智能芯片和智能系统的设计将会有很大的变化,编写CMD 文件就会很简单,甚至不需要了。
已经有芯片厂家做了一些这方面的工作,比如把电池和RAM 结合起来,就是一个能掉电保存的RAM。
它既可以作为传统的ROM 使用,又可以当RAM 使用。
但这显然只是一个暂时、折中的方法,其原理、成本、体积、容量还不如人意,不能算是“革命性”的进步。
我们平时在用到存储器的时候,要考虑哪些因素呢?首先必须确认,在你的使用场合,是要永久保存数据,还是暂时保存?这关系到选择非易失性,还是易失性存储器的大问题,是首要的问题。
在某些场合,如果必须永远地保存数据,即使希望速度快一些,也只能选择非易失的ROM 类存储器,而把速度问题放在其次,或者另外想办法解决;另外一些场合,却要把速度放在第一位,只要在通电期间能够始终保存数据,就够了,当然就要选择RAM 类的存储器了。
这两种情况我们都会遇到:程序代码一般都要存储在ROM 类存储器中,否则,从设备生产开始,储存、运输,一直到用户手里,要必备不间断电源,还要保证不发生断电的意外;程序运行的时候,为了提高速度,就必须在RAM 中运行,试想想,如果你的MP4放电影一停一顿的,谁还会用它看电影呢?所以ROM 和RAM 都是必不可少的,各有各的用途,而且,出于功能、参数、速度、读写方法、功耗、工艺、成本等方面的考虑,往往要同时使用不止一种存储器。
事实上,TI 在设计DSP芯片时,也遇到同样的问题,TI 考虑的情况要比我们更多,更复杂。
要知道,设计芯片的人是最牛X的,开发工程师只是跟在人家后面,在人家规定的框框里亦步亦趋。
翻开DSP的PDF文档,找到memory map 就会看到,芯片上集成了形形色色的存储器:FLASH、ROM、BROM、OTP ROM,SRAM、SARAM、DARAM、FIFO 等。
就2407和2812而言,如果是做个流水灯之类的小东东,DSP芯片加晶体加电源就可以了,片上集成的ROM 和RAM,在仿真状态下已经足够用了,烧写并脱离仿真器运行也足够。
所以,它们的最小系统不需要外扩任何存储器。
但也只能做简单的东东,往往还需要外扩一些ROM 和/或RAM 存储器,才能委以大用。
(顺便说一句,DSP的最小系统,要比8951芯片的最小系统大得多。
)千万不要被这些存储器的名称所迷惑!翻来覆去,其实就是两大类:非易失和易失。
初学者往往忽略了这一点。
两大类!记住这一点,CMD文件就是以这两类存储器为主轴,然后展开的。
DSP芯片的片内存储器,只要没有被TI占用,用户都可以全权支配。
TI设计了“CMD文件”这种与用户的接口形式,用户通过编写CMD 文件,来管理、分配系统中的所有物理存储器和地址空间。
CMD文件其实就是用户的“声明” ,包括两方面的内容:1、用户声明的整个系统里的存储器资源。
无论是DSP 芯片自带的,还是用户外扩的,凡是可以使用的、需要用到的存储器和空间,用户都要一一声明出来:有哪些存储器,它们的位置和大小。
如果有些资源根本用不到,可以视为不存在,不必列出来;列出来也无所谓。
2、用户如何分配这些存储器资源,即关于资源分配情况的声明。
用户根据自己的需要,结合芯片的要求,把各种数据分配到适当种类、适当特点、适当长度的存储器区域,这是编写CMD文件的重点。
用户编写完自己的程序以后,要经过开发环境(编译器)的安排和解释(即编译),转换为芯片可以识别的机器码,最后下载到芯片中运行。
CMD 文件就是在编译源程序、生成机器码的过程中,发挥作用的,它作为用户的命令或要求,交给开发环境(编译器)去执行:就这么分配!下面将从这两个方面入手,详细说明如何编写CMD文件。
三、编写CMD文件之——资源清单如上文所述,CMD 文件包含两大内容,首先就是存储器的资源清单,或者说,系统中(电路板上)可用的存储器资源。
TI 规定,CMD文件的资源清单用关键字“MEMORY”作为标识,具体内容写在后面的大括号{ } 里面。
如下面的形式:MEMORY{PAGE 0:xxx : org = 0x1234 , length = 0x5678 /*This is my house.*/PAGE 1:aaa : org = 0x1357 , length = 0x2468 /*My home here.*/}其中,MEMORY,PAGE n,org,length,包括冒号、等于号、花括号,都是关键字符,必不可少。
PAGE n表示把可用的资源空间再划分成几个大块,最多允许分256块,从PAGE 0到PAGE 255。
如果把MEMORY比作图书馆,PAGE n就是其中的“社科类” 、“工程类” 、“外文类”等。
大家都习惯于把PAGE 0作为程序空间,把PAGE 1作为数据空间。
如果你很好奇,也可以试试别的数字。
凡智能芯片,都离不开这两种“空间” ,大名鼎鼎的冯·诺依曼结构和哈佛结构,都是建立在程序空间和数据空间两种结构的基础上,我们面对的DSP也是如此。
只要学习过单片机,就很容易理解。
如果你构思出第三种结构,恭喜您,您将与这二位齐名了。
CMD文件中还可以写上注释,用“/*”和“*/”包围起来,但不允许用“//” ,这一点和C语言不同。
上面的例子,仅仅就是个“例子” ,不针对任何特定的芯片。
带注释的语句有两行,每一行都是一项声明,表示在程序空间或数据空间下,再细分更小的块,好比是“社科类”又分了几个书架。
比如xxx : org = 0x1234 , length = 0x5678 表示在程序空间PAGE 0里面,划分出一个命名为xxx的小块空间,起始地址从存储单元0x1234 开始,总长度为0x5678 个存储单元,地址和长度通常都以十六进制数表示。
所以,xxx空间的实际地址范围从0x1234开始,到0x1234 + 0x5678 – 1 = 0x68AB 结束(起始地址加长度再减一),这一段连续的存储区域,就属于xxx小块了。
上面的例子中,PAGE 0和PGAE 1各包含了只有一个“小块” ,用户可以根据自己的情况,按照同样的格式任意增加。
在支持多个CMD文件的开发环境里,某个或某几个CMD文件中,“小块”的数量可以为0,也就是说,关键字PAGE 0或PAGE 1下面,可以是空白的。
但不允许所有的CMD 文件的同一空间都是空白。
另外,没有资料提到过“小块”数量上限的限制,需要去查阅文档或咨询TI 公司。
很多关键字,还允许有别的写法,比如“org”可以写为“o” ,“length”可以写为“len” 。
这些规定和其他细节,可以去查阅TI 的pdf 文档,一般叫做“xxxxx Assembly Language Tools User's Guide.pdf” ,汇编语言工具指南,xxxxx是芯片的型号或系列。
但这个文档不适合初学者。
实践证明,至少对于C2000 系列的2407 和2812 而言,存储单元的单位是“字word” ,即16bit。