DSP編程技巧之17---非常「關鍵」的關鍵字

2021-01-07 電子產品世界

  什麼是「關鍵字」?關鍵字就是已被C語言本身使用,不能作其它用途使用的字,例如關鍵字不能用作變量名、函數名等。那「關鍵字」到底有多關鍵?簡單得說,就是如果不掌握它們的使用方法,程序就不能按照我們的設計產生預期的結果。C28x的編譯器支持所有的標準C89的關鍵字,包括const、volatile和register,標準的C99關鍵字,包括inline和restrict,以及支持TI自定義的擴展關鍵字__cregister、__asm,和__interrupt;對於FPU的操作,還支持restrict關鍵字。接下來我們就看一下幾個常用關鍵字的用法,包括const,cregister,far,__interrupt等。在前面的一篇文章DSP編程技巧之15-使用代碼優化時必須考慮的五大問題中,我們已經描述了volatile和restrict的用法,在此不再重複描述。

本文引用地址:http://www.eepw.com.cn/article/256730.htm

  1. const

  const關鍵字用來定義值不會發生變化/不允許被改變的變量、數組等,即相當於這些變量、數組是「只讀」的。通常情況下,const定義的全局變量會存放在cmd文件定義的.const段中,而.const段一般會被連結器分配到ROM或者FLASH存儲,而不是RAM中;考慮到片上ROM/FLASH的空間通常比RAM的空間大,且RAM的空間經常會比較緊張,這種存儲分配方式是很有優勢的。但是在兩種情況下const定義的全局變量仍然會被分配到RAM的地址空間中,包括:

  1) 使用const定義變量的同時還使用了volatile關鍵字,例如volatile const int x,volatile類型的變量是默認存放在RAM中的,volative const也會被分配到RAM中;程序中無法對volative const定義的常量進行修改(但是某些情況下外部程序可以對其修改)。

  2) 在函數的作用域內,對象被自動的存儲。

  在使用const關鍵字的時候,其位置是非常重要的,例如:

  int * const p = &x; //指針p為constant類型(p不可變),指向的內容為可變的int類型變量

  const int * q = &x; //指針q為可變的,指向constant的int類型

  使用const關鍵字,我們可以定義內容較多的常數型數據表(例如一個100點的自定義數學表),並把它們分配到ROM/Flash中,例如

  const int digits[] = {0,1,2,3,4,5,6,7,8,9};

  通常情況下我們會直接使用#define來預定義某些符號的值,那#define與const的區別是什麼? const定義的只讀變量在程序運行過程中只有一份拷貝(比如它存放在ROM中,有固定的地址),而#define定義的宏常量在內存中有若干個拷貝。#define宏是在預編譯階段進行替換,而const修飾的只讀變量是在編譯的時候確定其值。#define宏沒有類型,而const修飾的只讀變量具有特定的類型(該是啥類型還是啥類型,只不過其值為只讀的)。const 的好處是引入了常量的概念,讓我們不要去修改不該修改的內存;當我們不小心嘗試改變const變量的值時,編譯器就可以給出相關的錯誤信息提醒我們了。

  2. cregister

  使用cregister關鍵字,當我們定義的該類型的對象與C28x的標準的控制寄存器匹配時,編譯器會自動產生相關的代碼去控制對應的寄存器,使得我們可以在高級程式語言C/C++中對寄存器進行控制;如果不匹配則產生編譯器錯誤。目前可匹配此類型的寄存器包括:

  IER:中斷使能寄存器

  IFR:中斷標誌寄存器

  其定義方式為;

  extern cregister volatile unsigned int IFR;

  extern cregister volatile unsigned int IER;

  cregister類型只能對整形或者指針類型進行定義,並且只在本文件的作用域內生效,它既不能在函數內定義,也不能被用在浮點類型、結構體或者共同體類型上面。如果cregister類型定義的變量是可以被外部控制修改的,那麼該變量也必須同時使用volatile類型進行聲明。

  在定義了寄存器之後,我們就可以直接使用寄存器的名字了,但是還有以下的限制(如果不按照規範來,則會有「Illegal use of control register」的錯誤提示):

  1)IFR是不能直接寫的,它的置位操作只能通過「或」操作(操作符是|)進行修改,且操作數必須是立即數,它的復位操作只能被「與」操作(操作符是&)進行修改,例如:

  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選項實現的。)

  當一個變量被定義為far類型時,它被存儲在高於64K的地址範圍中,此時far類型的全局變量不再保存在.bss段中,而是保存在一個新的段,即.ebss中,相同的道理,far類型的const變量也被保存到.econst段中。注意:只有全局變量和靜態變量可以被定義為far類型,函數中的非靜態變量(自動存儲對象)因為被分配到棧中,被自動當near類型來處理。對於結構體,如果結構體被聲明為far類型,則全部成員都會自動繼承為far類型。舉例如下;

  int far *ptr; // 指針指向far類型的int,但是指針本身是near類型的

  int * far ptr; // 指針指向near類型的int,但是指針本身是far類型的

  int far * far ptr; //指針和指向的內容都是far類型的

  int far *memcpy_ff(far void *dest, const far void *src, int count);

  // 函數的參數為兩個far類型的指針,且返回值也為far類型的指針

  int *far func();// 錯誤:far類型只能用於數據,不能用於函數

  //因為程序地址空間本身就是22位的

  最後需要注意的是,目前對於兩個far類型指針相減的操作,其結果是16位的指針。

  4. _interrupt

  __interrupt用來聲明一個函數是中斷處理函數;在嚴格的ANSIC/C++模式下,也可以使用interrupt關鍵字來代替。中斷處理函數要遵循特殊的寄存器保存規則和退出順序,從而保證代碼的安全。在C/C++程序中產生中斷時,所有被中斷子程序使用,或者被中斷子程序調用的函數使用的狀態都需要被保留。此外,__interrupt定義的函數不能有參數,也沒有返回值,即:

  __interrupt void int_handler()

  {

  unsigned int flags;

  ...

  }

  唯一特殊的是c_int00函數,它是C/C++程序的入口點,被系統保留為默認的復位中斷函數,並在其中調用main函數。因為c_int00函數不被任何函數所調用,所以它不需要保存任何狀態(畢竟是在復位和初始化狀態)。

  在DSP/BIOS和SYS/BIOS HWI對象中,不需要使用__interrupt關鍵字,因為Hwi_enter/Hwi_exit宏和Hwi解包器已經包含了該函數,此時使用__interrupt關鍵字會產生負面的效果。

相關焦點

  • 第六講 DSP在雷達信號處理中的應用
    本文重點介紹通用dsp在雷達信號處理系統中的典型應用,以及研製基於dsp的雷達信號處理系統的關鍵技術。本文引用地址:http://www.eepw.com.cn/article/20739.htm dsp在雷達信號處理中的典型應用 作為面向數位訊號處理的可編程嵌入式處理器,dsp具有高速、靈活、可靠、可編程、低功耗、接口豐富、處理速度快、實時性好等特點。
  • DSP編程技巧之18---不得不看的編譯指示
    都是對特定源文件使能MISRA-C:2004規則檢查(汽車工業軟體可靠性聯會),使用方法是:  #pragma CHECK_MISRA (" {all|required|advisory|none|rulespec} ");  其中的rulespec是具體MISRA中的規則,使用方法請參考DSP編程技巧之
  • DSP編程技巧之24---C/C++與彙編語言的交互之-(2)從C/C++代碼調用...
    在C/C++與彙編語言混合編程的情況下,一般我們都會選擇C/C++來實現所期待的大部分功能,對於少數和硬體關聯度高(例如操作某些CPU寄存器)以及對運算的實時性要求高(例如高速、多點的FFT)的功能才使用彙編來實現,這就使得大多數情況下,C/C++與彙編的交互都是從C/C++代碼調用彙編代碼中的函數與變量,所以在此我們就來看一下這種調用的規則。
  • DSP編程技巧之30---答疑解惑哪家強之(5)
    初學者往往使用printf列印「Hello World」這樣的方式來完成第一個DSP編程的程序,這種方法雖然是非常直觀明了的,感覺起來功能也是非常簡單的,但是一編譯結果發現提示棧的空間不夠,或者有「program will not fit into available memory」之類的錯誤。
  • 基於小波變換與DSP的實時音頻視頻處理系統
    解碼過程與之相反,壓縮數據由主機送入fifo,解碼後產生ccir-656格式的數據視頻數據,從數字視頻接口輸出。 adv611與其前期產品adv601,adv601lc相比,他不僅有更寬的溫度範圍(-25~+85℃),而且採用硬體減幀技術,可獲得更高的壓縮比(最大可達7 500:1)並且增加一種稱為特性盒控制的功能。
  • Steam 新遊推薦 04-17
    /17(中文支持) 一款新的大富翁類遊戲。 在模擬日本全國的棋盤地圖上淘汰對手、奔向目的地、爭奪第一富豪之位的新感覺桌面類遊戲《億萬富翁之路》登場!努力買斷全國的產業,成為金融霸者吧!
  • 給大家推薦12個非常有效的關鍵字研究與挖掘工具
    您可能不知道的一件事是,您可以在Autosuggest中看到最多十個建議的關鍵字:Google AutoSuggest現在您將獲得更多建議,這裡有一個小技巧。大多數SEO關鍵字工具都非常難看,但這個工具包含了一些很棒的用戶體驗和設計。費用:免費適用於:搜索以漂亮的顯示方式提出問題。當你需要在博客文章或報告中向客戶展示某些東西時,這很棒。
  • Java 編程技巧之數據結構
    作者 | 常意責編 | 屠敏導讀唐宋八大家之一歐陽修在《賣油翁》中寫道:翁取一葫蘆置於地,以錢覆其口,徐以杓酌油瀝之,自錢孔入,而錢不溼。因曰:「我亦無他,唯手熟爾。」編寫代碼的"老司機"也是如此,"老司機"之所以被稱為"老司機",原因也是"無他,唯手熟爾"。
  • 基於DSP和FPGA的機器人聲控系統設計與實現
    系統硬體分為語音信號的採集和播放,基於dsp的語音識別,fpga動作指令控制、步進電機及其驅動、dsp外接快閃記憶體晶片,jtag口仿真調試和鍵盤控制幾個部分。工作流程是麥克風將人的語音信號轉化為模擬信號,在經過音頻晶片tlv320aic23量化轉化成數位訊號輸入dsp.dsp完成識別後,輸出動作指令。 fpga根據dsp輸入的動作指令產生正確的正反轉信號和準確的脈衝給步進電機驅動晶片,驅動晶片提供步進電機的驅動信號,控制步進電機的轉動。片外flash用於存儲系統程序和語音庫並完成系統的上電加載。
  • Java之this關鍵字的用法
    給位小夥伴們大家好,在之前的文章中,小編有講過super關鍵字的用法Java之super關鍵字的用法。這次小編要介紹的是在Java當中this關鍵字的用法。具體如下:1.在本類的成員方法中,訪問本類的成員變量。
  • 使用STM32 的DSP庫進行FFT變換
    /**********************************************************************************************************FileName:dsp_asm.h*******************************************
  • Python 為啥沒有 void 關鍵字呢
    void 是程式語言中最常見的關鍵字之一,從字面上理解,它是「空的、空集、空白」的意思,最常用於表示函數的一種返回值類型。在 C、Algol68 及它們所派生的幾種程式語言中,void 類型是函數正常返回的一種類型,但是不會給調用者返回一個值。簡單來說,void 是一種類型(type),但是沒有具體的值(value)。這到底是什麼意思呢?
  • python編程30個常用技巧
    打開APP python編程30個常用技巧 深度學習這件小事 發表於 2020-12-24 15:07:51 1、冒泡排序
  • 少兒編程思維之模式識別
    編程思維"作為"計算思維"的分支,結合數學和工程學的思維方法,把計算機當成是我們最有力的助手,通過計算機來實現我們平時不敢去嘗試的瘋狂想法和解決方法。模式識別是指通過找出相似之處,從而聯想到類似的更簡單的情景或問題,從而幫助我們更簡單地去理解問題和解決問題。在數學中,給出一些數1、2、4、7、11、____,請問最後下一個數應該是多少?
  • 2019-2025年dsp晶片市場深度調查分析及發展前景研究報告
    《2019-2025年dsp晶片市場深度調查分析及發展前景研究報告》首先介紹了dsp晶片的背景知識,包括dsp晶片的相關概念、分類、應用、產業鏈結構、產業概述,國際市場動態分析,國內市場動態分析,宏觀經濟環境分析及經濟形勢對dsp晶片行業的影響,dsp晶片行業國家政策及規劃分析,dsp晶片產品技術參數,生產工藝技術,產品成本結構等;接著統計了中國主要企業
  • Java之super關鍵字的用法
    各為小夥伴們大家好,這次小編要介紹的是Java當中super關鍵字的用法,在上面的文章中小編有講過,super關鍵字是用來調用父類之間的成員變量和成員方法。現在小編來總結一下super關鍵字的用法。具體如下:1.在子類的成員方法中,訪問父類的成員變量。
  • 基於DSP的數字掃描探針顯微鏡的硬體解決方案研究
    該方案和圖1的明顯區別的是,圖2方案在spm控制板上添加了一塊dsp晶片,spm控制板和計算機信息交換將先通過dsp作相應處理,然後再送至對方,dsp和計算機的通信採用全雙工rs-232串口通信方式。
  • C語言中const關鍵字的妙用總結
    請看正文學習了多年的C語言,你對const關鍵字的使用全都掌握了嗎在編程實踐中你對const的使用是否有困惑呢?今天就給大家一起來探討總結,期望能夠大家解惑並提供參考。C語言中const關鍵字是constant的縮寫,通常翻譯為常量、常數等,有些朋友一看到const關鍵字馬上就想到了常量。事實上在C語言中const功能很強大,它可以修飾變量、數組、指針、函數參數等。
  • LabVIEW編程技巧:功能強大的變體數據類型用法
    變體數據類型簡介LabVIEW是一種圖形化程式語言,所以也叫G語言,在程序框圖上連線時,必須相同類型或者能強制相互轉換的類型埠才能連接在一起,例如我們不能將一個數值型的控制項連接到布爾型的控制項上,也不能將一個數組類型的控制項連接到簇類型的控制項上。
  • DSP編程技巧之12-揭開編譯器神秘面紗之代碼規範MISRA-C
    此外,其他產業也已經逐漸開始使用MISRA C:包括航空航天、電信、國防、醫療設備、鐵路等領域中都已有廠商使用MISRA C:這些領域無一不對代碼的規範,特別是代碼的安全有非常高的要求。MISRA C的第一版《Guidelines for the use of the C language in vehicle based software》是在1998年發行,一般稱為MISRA-C:1998.。