《電子技術應用》
您所在的位置:首頁 > 可編程邏輯 > 業(yè)界動態(tài) > DSP編程技巧之:非常“關鍵”的關鍵字

DSP編程技巧之:非常“關鍵”的關鍵字

2015-09-18
關鍵詞: DSP 編程技巧

  什么是“關鍵字”?關鍵字就是已被C語言本身使用,不能作其它用途使用的字,例如關鍵字不能用作變量名、函數(shù)名等。那“關鍵字”到底有多關鍵?簡單得說,就是如果不掌握它們的使用方法,程序就不能按照我們的設計產(chǎn)生預期的結(jié)果。C28x的編譯器支持所有的標準C89的關鍵字,包括const、volatile和register,標準的C99關鍵字,包括inline和restrict,以及支持TI自定義的擴展關鍵字__cregister、__asm,和__interrupt;對于FPU的操作,還支持restrict關鍵字。接下來我們就看一下幾個常用關鍵字的用法,包括const,cregister,far,__interrupt等。在前面的一篇文章DSP編程技巧之15-使用代碼優(yōu)化時必須考慮的五大問題中,我們已經(jīng)描述了volatile和restrict的用法,在此不再重復描述。
  1. const
  const關鍵字用來定義值不會發(fā)生變化/不允許被改變的變量、數(shù)組等,即相當于這些變量、數(shù)組是“只讀”的。通常情況下,const定義的全局變量會存放在cmd文件定義的.const段中,而.const段一般會被鏈接器分配到ROM或者FLASH存儲,而不是RAM中;考慮到片上ROM/FLASH的空間通常比RAM的空間大,且RAM的空間經(jīng)常會比較緊張,這種存儲分配方式是很有優(yōu)勢的。但是在兩種情況下const定義的全局變量仍然會被分配到RAM的地址空間中,包括:
  1) 使用const定義變量的同時還使用了volatile關鍵字,例如volatile const int x,volatile類型的變量是默認存放在RAM中的,volative const也會被分配到RAM中;程序中無法對volative const定義的常量進行修改(但是某些情況下外部程序可以對其修改)。
  2) 在函數(shù)的作用域內(nèi),對象被自動的存儲。
  在使用const關鍵字的時候,其位置是非常重要的,例如:
  int * const p = &x; //指針p為constant類型(p不可變),指向的內(nèi)容為可變的int類型變量
  const int * q = &x; //指針q為可變的,指向constant的int類型
  使用const關鍵字,我們可以定義內(nèi)容較多的常數(shù)型數(shù)據(jù)表(例如一個100點的自定義數(shù)學表),并把它們分配到ROM/Flash中,例如
  const int digits[] = {0,1,2,3,4,5,6,7,8,9};
  通常情況下我們會直接使用#define來預定義某些符號的值,那#define與const的區(qū)別是什么? const定義的只讀變量在程序運行過程中只有一份拷貝(比如它存放在ROM中,有固定的地址),而#define定義的宏常量在內(nèi)存中有若干個拷貝。#define宏是在預編譯階段進行替換,而const修飾的只讀變量是在編譯的時候確定其值。#define宏沒有類型,而const修飾的只讀變量具有特定的類型(該是啥類型還是啥類型,只不過其值為只讀的)。const 的好處是引入了常量的概念,讓我們不要去修改不該修改的內(nèi)存;當我們不小心嘗試改變const變量的值時,編譯器就可以給出相關的錯誤信息提醒我們了。

  2. cregister
  使用cregister關鍵字,當我們定義的該類型的對象與C28x的標準的控制寄存器匹配時,編譯器會自動產(chǎn)生相關的代碼去控制對應的寄存器,使得我們可以在高級編程語言C/C++中對寄存器進行控制;如果不匹配則產(chǎn)生編譯器錯誤。目前可匹配此類型的寄存器包括:
  其定義方式為;
  extern cregister volatile unsigned int IFR;
  extern cregister volatile unsigned int IER;
  cregister類型只能對整形或者指針類型進行定義,并且只在本文件的作用域內(nèi)生效,它既不能在函數(shù)內(nèi)定義,也不能被用在浮點類型、結(jié)構(gòu)體或者共同體類型上面。如果cregister類型定義的變量是可以被外部控制修改的,那么該變量也必須同時使用volatile類型進行聲明。
  在定義了寄存器之后,我們就可以直接使用寄存器的名字了,但是還有以下的限制(如果不按照規(guī)范來,則會有“Illegal use of control register”的錯誤提示):
  1)IFR是不能直接寫的,它的置位操作只能通過“或”操作(操作符是|)進行修改,且操作數(shù)必須是立即數(shù),它的復位操作只能被“與”操作(操作符是&)進行修改,例如:
  IFR |= 0x4;
  IFR &= 0x0800
  2)IER寄存器除了通過“或”操作或者“與”操作進行修改之外,也可直接賦值,例如:
  IER = x;
  IER |= 0x100;
  printf("IER = %x\n", IER);
  3. far
  默認情況下,C/C++的編譯器只支持到低64K的存儲空間,且所有的指針都默認為16位的。但是C28x的存儲空間一般都在16bit以上,此時通過使用far類型,C代碼中的指針可以為22bit寬(需要兩個存儲單元來存儲),并支持對高達4M的存儲空間的存取。(在C++中,不支持far關鍵字,對高地址的存取是通過使用在編譯器選項中開啟large memory model選項實現(xiàn)的。)

  當一個變量被定義為far類型時,它被存儲在高于64K的地址范圍中,此時far類型的全局變量不再保存在.bss段中,而是保存在一個新的段,即.ebss中,相同的道理,far類型的const變量也被保存到.econst段中。注意:只有全局變量和靜態(tài)變量可以被定義為far類型,函數(shù)中的非靜態(tài)變量(自動存儲對象)因為被分配到棧中,被自動當near類型來處理。對于結(jié)構(gòu)體,如果結(jié)構(gòu)體被聲明為far類型,則全部成員都會自動繼承為far類型。舉例如下;
  int far *ptr; // 指針指向far類型的int,但是指針本身是near類型的
  int * far ptr; // 指針指向near類型的int,但是指針本身是far類型的
  int far * far ptr; //指針和指向的內(nèi)容都是far類型的
  int far *memcpy_ff(far void *dest, const far void *src, int count);
  // 函數(shù)的參數(shù)為兩個far類型的指針,且返回值也為far類型的指針
  int *far func();// 錯誤:far類型只能用于數(shù)據(jù),不能用于函數(shù)
  //因為程序地址空間本身就是22位的
  最后需要注意的是,目前對于兩個far類型指針相減的操作,其結(jié)果是16位的指針。
  4. _interrupt
  __interrupt用來聲明一個函數(shù)是中斷處理函數(shù);在嚴格的ANSIC/C++模式下,也可以使用interrupt關鍵字來代替。中斷處理函數(shù)要遵循特殊的寄存器保存規(guī)則和退出順序,從而保證代碼的安全。在C/C++程序中產(chǎn)生中斷時,所有被中斷子程序使用,或者被中斷子程序調(diào)用的函數(shù)使用的狀態(tài)都需要被保留。此外,__interrupt定義的函數(shù)不能有參數(shù),也沒有返回值,即:
  __interrupt void int_handler()
  {
  unsigned int flags;
  ...
  }
  唯一特殊的是c_int00函數(shù),它是C/C++程序的入口點,被系統(tǒng)保留為默認的復位中斷函數(shù),并在其中調(diào)用main函數(shù)。因為c_int00函數(shù)不被任何函數(shù)所調(diào)用,所以它不需要保存任何狀態(tài)(畢竟是在復位和初始化狀態(tài))。
  在DSP/BIOS和SYS/BIOS HWI對象中,不需要使用__interrupt關鍵字,因為Hwi_enter/Hwi_exit宏和Hwi解包器已經(jīng)包含了該函數(shù),此時使用__interrupt關鍵字會產(chǎn)生負面的效果。

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權歸版權所有權人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認版權者。如涉及作品內(nèi)容、版權和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經(jīng)濟損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。
主站蜘蛛池模板: 国产卡一 | 国产麻豆一级在线观看 | 久久狠狠色噜噜狠狠狠狠97 | 亚洲午夜久久 | 精品国产品欧美日产在线 | 天天拍夜夜添久久精品中文 | 日韩视频免费在线观看 | 日韩国产欧美成人一区二区影院 | 性生交大片免费一级 | 日韩中文字幕精品免费一区 | 亚洲国产天堂在线mv网站 | 黄色在线观看www | 在线成人免费 | 最刺激黄a大片免费网站 | 免费在线看黄色片 | 天天天天操 | 污视频网站免费观看 | 免费伊人网 | 国产2021久久精品 | 日韩图片专区 | 天天噜日日噜夜夜噜 | 一本大道道无香蕉综合在线 | 91欧美在线 | 中文字幕一区二区三区精彩视频 | 久久免费观看国产精品 | 在线中文字幕观看 | 操人网站 | 国产高清美女一级a毛片久久 | 又黄又爽又猛大片录像 | 亚洲三级视频在线观看 | 国产精品一区二区三区久久 | 一级特黄高清完整大片 | 免费黄网站在线看 | 亚洲福利| 深夜在线影院 | 日本综合在线 | 国产伦理在线播放 | 一级毛片在线免费播放 | 亚洲噜噜噜噜噜影院在线播放 | 日本天天色 | 日韩精品在线观看视频 |