×

DSP编程技巧之建立main函数运行环境

消耗积分:0 | 格式:rar | 大小:0.1 MB | 2017-10-20

分享资料个

  在一个C/C++程序能正常运行之前,相关的C/C++运行时(run-time)环境首先要正确建立。在CCS软件编程的情况下,C/C++的实时运行库RTS的源程序库rts.src中包含了名为boot.c或者boot.asm的启动程序(在一些TI的例子里,则使用了CodeStartBranch.asm来完成启动工作,它会自动调用库文件中的boot.asm),用于在系统启动后调用c_int00函数,并通过其中的操作来完成运行时环境的建立。通常情况下,c_int00函数位于rts2800.lib库函数中的boot.obj(即TI官方编译boot.c或者boot.asm生成的目标文件)下,这也就是为什么我们在C28x编程的情况下通常要把rts2800.lib库函数加入工程中的原因(其它器件则根据型号、系列添加对应的库文件;否则就会出现初学者经常遇到的找不到boot.c之类的错误)。

  注:小型内存模型含义是已初始化的段被链接至低 64Kw(字)可寻址空间内的非易失性内存,它使用rts2800.lib。对于定点器件,如果使用大内存模型(超过64K字),则需要使用库 rts2800_ml.lib;对于含有FPU的器件,用于标准 C 语言代码的为 rts2800_fpu32.lib,或者用于 C++ 代码的 rts2800_fpu32_eh.lib(没有针对浮点器件的较小内存模型库)。在 CCS v5/v6 中,有一个针对库的“自动”设置,此设置可据项目的设置(例如,浮点支持和内存模型选择)让 CCS 自动选择正确的库来使用。对于 DSP/BIOS 项目,DSP/BIOS 将负责将所需的库包括在内,我们用户不需要在项目中包含任何运行支持库。

  如果在链接器选项中我们使用了--ram_model或者--rom_mode,则_c_int00函数自动被配置为整个程序执行的入口点。此外,在CPU复位之后(相当于一个软件或者硬件的复位中断),我们也可以把整个程序的入口点指向_c_int00,例如:

  .def _Reset

  .ref _c_int00

  _Reset: .vec _c_int00, USE_RETA

  则在执行CPU复位操作之后,系统自动跳转到_c_int00函数。

  在c_int00函数中完成的功能主要有:

  1. 设置/初始化CPU的状态和配置寄存器。

  2. 为系统的栈定义一个.stack段,然后建立并初始化栈的指针。其中,栈需要被分配在单一的、连续的一段地址中,起始点为低地址,终点为高地址,栈指针SP的初始化值指向栈的顶端。

  3. 从初始化表中,把数据复制到.bss段中,从而初始化全局变量。如果使用了—ram_model选项在加载程序时就初始化变量,则在程序运行前,会首先运行一个加载程序来完成变量的初始化。如果使用了--rom_model选项,则使用.cinit中的运行时初始化表来完成变量的初始化。

  默认情况下,链接器使用--rom_model选项,在程序运行时完成变量的自动初始化。在程序运行时,.cinit段和其它初始化的段会被一起加载到内存中,从而使得C/C++的启动程序可以自动把.cinit中的初始化表格复制到.bss段中,完成全局变量的自动初始化。这种方法的特点在于,初始化的表格可以被存放在更加便宜且大容量的ROM或者FLASH,而不是RAM中,并且可以在程序启动时再自动加载到RAM中,这种方法在我们把程序烧写到FLASH中再运行的时候是经常使用的。关于Flash运行的更多信息,可以参考TI的的一个应用报告:http://www.ti.com.cn/cn/lit/an/zhca550l/zhca550l.pdf,从 TMS320F28xxx 数字信号处理器 (DSP) 上的内部闪存存储器上运行一个应用。

  如果使用—ram_model的链接器选项,则链接器会在.cinit段的开头中配置STYP_COPY位(0010h),告诉加载器不要把.cinit段自动加载到内存中,并且把cinit这个符号设置为-1(默认情况下符号cinit指向初始化表格),从而向启动程序表明,内存中没有初始化表格,在启动时不需要执行运行时的初始化工作。在这种情况下,需要我们自定义一个加载程序,从而在加载程序时就完成初始化,它的主要内容包括:

  ü 在目标文件中检测.cinit段的存在;

  ü 在.cinit段的开头配置STYP_COPY位,使得该段不会被自动复制到内存中;

  ü 需要我们理解并正确遵循初始化表格的格式。

  这三个注意点貌似比较复杂,不过有读者可能会问,我们在直接把程序通过JTAG下载到DSP的RAM中并运行的时候,貌似并没有配置这么麻烦的步骤啊?那是因为CCS编程环境已经帮我们承担了这一重要任务,在我们用仿真器来调试、运行的时候经常会使用到这个方式。

  注意:在C/C++程序运行之前,一些全局变量必须被赋予初始值。在ANSI/ISO C中,未明确初始化的全局和静态变量在程序执行前都需要被初始化为0,C/C++的编译器并不会对它们进行自动初始化。在把程序加载到RAM而不是ROM中的情况下,比较方便的方法是直接把.bss段初始化为0。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.lene-v.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'DSP编程技巧之建立main函数运行环境',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.lene-v.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);