基於ADS1.2下的ARM應用開發
1.巨集定義中volatile uint8
UINT8等效於unsigned char,而volatile關鍵字主要作用是針對變數可能在編譯器控制之外被修改的情況,強制讓編譯器放棄對這個變數的優化。volatile:因為C編譯器的優化作用以及作業系統的cache等的影響,某些變數的值在記憶體中和暫存器中是不一致的。這對單指令流程式沒有影響,但對有中斷處理函式、多執行緒應用等而言,會造成混亂。因此,C裡提供了volatile修飾符強制要求該變數必須從記憶體訪問,也就是告訴編譯器該變數可能在任何時候被修改。
2.定義暫存器處理函式的函式巨集。
帶引數的巨集也被稱為"函式巨集". 利用巨集可以提高程式碼的執行效率: 子程式的呼叫需要壓棧出棧, 這一過程如果過於頻繁會耗費掉大量的CPU運算資源. 所以一些程式碼量小但執行頻繁的程式碼如果採用帶引數巨集來實現會提高程式碼的執行效率.如:
#define _CLR(REG,n) REG = REG ^ (1 << n) //n位置0.
#define _SET(REG,n) SET = REG | (1 << n) //n位置1.
3.型別的強制轉換
型別的強制轉換格式上需要有括號來標定,如:
資料的轉換:unit8 data8;
float b;
b = (float)data8;……
指標的轉換:unit8 *point8;
unit8 data8;
point8 = (unit8*)data8;……
4.extern用法
1) 基本解釋
extern可以置於變數或者函式前,以標示變數或者函式的定義在別的檔案中,提示編譯器遇到此變數和函式時在其他模組中尋找其定義。另外,extern也可用來進行連結指定。
2 )問題:extern 變數在一個原始檔裡定義了一個陣列:char a[6];在另外一個檔案裡用下列語句進行了宣告:extern char *a;請問,這樣可以嗎?
答案與分析:
(1)、不可以,程式執行時會告訴你非法訪問。原因在於,指向型別T的指標並不等價於型別T的陣列。extern char *a宣告的是一個指標變數而不是字元陣列,因此與實際的定義不同,從而造成執行時非法訪問。應該將宣告改為extern char a[ ]。
(2)、例子分析如下,如果a[] = "abcd",則外部變數a=0x61626364 (abcd的ASCII碼值),*a顯然沒有意義。顯然a指向的空間(0x61626364)沒有意義,易出現非法記憶體訪問。
(3)、這提示我們,在使用extern時候要嚴格對應宣告時的格式,在實際程式設計中,這樣的錯誤屢見不鮮。
(4)、extern用在變數宣告中常常有這樣一個作用,你在*.c檔案中宣告瞭一個全域性的變數,這個全域性的變數如果要被引用,就放在*.h中並用extern來宣告。
3) 問題:extern 函式2
當函式提供方單方面修改函式原型時,如果使用方不知情繼續沿用原來的extern申明,這樣編譯時編譯器不會報錯。但是在執行過程中,因為少了或者多了輸入引數,往往會照成系統錯誤,這種情況應該如何解決?
答案與分析:
目前業界針對這種情況的處理沒有一個很完美的方案,通常的做法是提供方在自己的xxx_pub.h中提供對外部介面的宣告,然後呼叫方include該標頭檔案,從而省去extern這一步。以避免這種錯誤。寶劍有雙鋒,對extern的應用,不同的場合應該選擇不同的做法。
4) 問題:extern “C”
在C++環境下使用C函式的時候,常常會出現編譯器無法找到obj模組中的C函式定義,從而導致連結失敗的情況,應該如何解決這種情況呢?
答案與分析:
C++語言在編譯的時候為了解決函式的多型問題,會將函式名和引數聯合起來生成一箇中間的函式名稱,而C語言則不會,因此會造成連結時找不到對應函式的情況,此時C函式就需要用extern “C”進行連結指定,這告訴編譯器,請保持我的名稱,不要給我生成用於連結的中間函式名。
下面是一個標準的寫法:
//在.h檔案的頭上
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* __cplusplus */
…
…
//.h檔案結束的地方
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
5)問題:extern 函式1
常常見extern放在函式的前面成為函式宣告的一部分,那麼,C語言的關鍵字extern在函式的宣告中起什麼作用?
答案與分析:
如果函式的宣告中帶有關鍵字extern,僅僅是暗示這個函式可能在別的原始檔裡定義,沒有其它作用。即下述兩個函式宣告沒有明顯的區別:extern int f(); 和int f();當然,這樣的用處還是有的,就是在程式中取代include “*.h”來宣告函式,在一些複雜的專案中,我比較習慣在所有的函式宣告前新增extern修飾。
5.ADS開發時,注意結構體和指標的轉換!結構體可以用指標來完成,例項化後也可以用地址來引用!
在嵌入式C中,我們經常用結構體來封裝一些相關的資料,這樣易於閱讀!對於指標的應用要謹慎!另外,如果能彙編,直接可以在C中嵌入彙編,利用好了,可提高程式的執行效率!
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/lanqiong0817/archive/2009/04/12/4065419.aspx
我的網站,有興趣的可以去看看,寫點東西,給我拉拉人氣:http://www.k557.com/bbs/
forum.php?gid=59
相關文章
- 基於Yii2的應用開發引擎RageFrame
- 基於Laravel 5.4 開發單頁應用Laravel
- 基於PostgreSQL進行Java應用開發SQLJava
- 基於 VSCode下的 Flutter 開發VSCodeFlutter
- 《Flask Web開發 基於Python的Web應用開發實戰》簡評FlaskWebPython
- 基於vue開發的線上付費課程應用Vue
- 官方翻譯 | 有關基於文件的iOS應用開發iOS
- 基於以太坊的58同城 | DApp開發與應用案例APP
- 基於 WebRTC 與 Webcam 開發一個聊天應用Web
- 基於大模型的人工智慧應用開發大模型人工智慧
- 基於 Vue3 開發的 Lumen IM 線上聊天應用Vue
- 基於 Vue2.0 開發的 Lumen IM 線上聊天應用Vue
- 鴻蒙系統應用開發之基於API6的藍芽開發鴻蒙API藍芽
- 安裝用於 Windows 應用開發的工具Windows
- 基於springmvc+spring-data-jpa+dubbo開發web應用SpringMVCWeb
- 基於SkyEye執行Qt:著名應用程式開發框架QT框架
- 基於eTS高效開發HarmonyOS課程類應用ASGR
- 基於React的表單開發的分析(下)React
- 《Flask Web開發:基於Python的Web應用開發實戰》學習筆記(二)FlaskWebPython筆記
- 使用Spring Boot開發基於Kubernetes的Zeebe工作流應用 – SalaboySpring Boot
- 分享剛出爐的基於Blazor技術的Web應用開發框架BlazorWeb框架
- 基於TRIZ架構下的網路安全與應用架構
- 基於雲資料庫MongoDB版進行應用開發資料庫MongoDB
- 基於區塊鏈技術落地應用開發-食品溯源區塊鏈
- 《SpringBoot實戰開發》——基於Gradle+Kotlin的企業級應用開發最佳實踐Spring BootGradleKotlin
- 基於迅為4418開發板應用於智慧門禁系統案例
- Docker下Nacos配置應用開發Docker
- 基於flask的最小的應用Flask
- 《基於MVC的javascript web富應用開發》中的一些函式MVCJavaScriptWeb函式
- 基於 abp vNext 微服務開發的敏捷應用構建平臺 - 框架分析微服務敏捷框架
- 亞信科技基於 Apache SeaTunnel 的二次開發應用實踐Apache
- 基於OpenCV+dlib開發一個人臉識別應用OpenCV
- Dubbo 入門系列之基於 Dubbo API 開發微服務應用API微服務
- 基於知名微服務框架go-micro開發gRPC應用程式微服務框架GoRPC
- 基於Dapr的 Azure 容器應用
- 用 Visual Studio Code 做基於 .NET MAUI 跨平臺移動應用開發UI
- spring boot + vue + element-ui全棧開發入門——基於Electron桌面應用開發Spring BootVueUI全棧
- 基於全志A40i開發板——Linux-RT核心應用開發教程(1)Linux
- 基於RDD的Spark應用程式開發案列講解(詞頻統計)Spark