|
引言7 q* {9 `' k1 D& `* \! s
說到預(yù)編譯,大家立刻就能想到#define、#if、#ifdef和#ifndef等熟悉的預(yù)編譯命令。其實(shí)#include,我們通常放在源文件用來包含頭文件,它也是預(yù)編譯命令。當(dāng)然這不是這篇文章的重點(diǎn)。這篇文章主要講解下#error預(yù)編譯命令,對(duì)于什么是預(yù)編譯,預(yù)編譯的作用等基礎(chǔ)知識(shí)點(diǎn)不再講解,不懂的同學(xué)請(qǐng)自行百度。在MCU的開發(fā)中,我們經(jīng)常需要用到Flash存儲(chǔ)一些參數(shù),且通常情況下有很多參數(shù)需要存儲(chǔ)。一般采用一個(gè)扇區(qū)存儲(chǔ)一種類型的參數(shù)(可能造成Flash空間浪費(fèi)),但對(duì)于一些內(nèi)部Flash容量很大的MCU,這樣做也是可行的。示例demo如下#define PARA_BATTERY_ADDR 0x08019000 //存儲(chǔ)電池參數(shù)#define PARA_ETH_ADDR 0x0801B800 //存儲(chǔ)網(wǎng)絡(luò)參數(shù)..........#define PARA_USER_CONFIG_ADDR 0x0801C400 //存儲(chǔ)用戶參數(shù)很多開發(fā)工程師喜歡這樣做,如果參數(shù)少時(shí)還好,當(dāng)有很多參數(shù)時(shí),這將是一個(gè)噩夢(mèng)。如果這些參數(shù)分散在各個(gè)文件中,閱讀這份源碼將是惡心他媽給惡心開門,惡心到家了。8 r; U9 W7 S3 C0 Q4 T% ]! P
當(dāng)想增加一個(gè)參數(shù)存儲(chǔ)時(shí),如果不很熟悉代碼,根本不知道哪個(gè)扇區(qū)是空閑的。
4 }- ?; N6 s) a7 g/ ]5 [) @優(yōu)化版本如下,將這這些宏定義統(tǒng)一定義在flashmap.h中#define PARA_STARADDR (0x08000+(100*1024)) //前100K用于存儲(chǔ)固件,參數(shù)存儲(chǔ)開始地址。#define FLASH_SECTOR_SIZE (2*1024) //Flash每個(gè)扇區(qū)的大小. t8 s' l1 C5 A: U
#define PARA_BATTERY_ADDR PARA_STARADDR //存儲(chǔ)電池參數(shù)#define PARA_BATTERY_SIZE (1*FLASH_SECTOR_SIZE) //電池參數(shù)所占空間大小8 }. w7 X. s8 d0 Z/ h# ^
#define PARA_ETH_ADDR (PARA_BATTERY_ADDR+PARA_BATTERY_SIZE) //存儲(chǔ)網(wǎng)絡(luò)參數(shù)#define PARA_ETH_SIZE (2*FLASH_SECTOR_SIZE) //網(wǎng)絡(luò)參數(shù)所占空間大小相信大家也看出來了,這樣管理參數(shù)地址,就顯得很合理,不會(huì)想增加一個(gè)參數(shù)時(shí),不知道哪個(gè)扇區(qū)是空閑的,找到了一個(gè)扇區(qū),還是擔(dān)心受怕,害怕和別的參數(shù)存儲(chǔ)地址沖突將其覆蓋。當(dāng)然它也有弊端,如果問你PARA_ETH_ADDR存儲(chǔ)地址,并不能立刻從代碼中看出,這個(gè)問題,我一般使用printf打印出來。還有個(gè)問題,如果加了很多參數(shù),最后一個(gè)參數(shù)地址大于Flash空間怎么辦,或者軟件設(shè)計(jì)一段Flash空間作為參數(shù)區(qū),不被允許超過這個(gè)地址。在這個(gè)代碼結(jié)構(gòu)中,無法從代碼中直接獲取,有不行使用printf肉眼判斷,那么可以使用#error 解決這個(gè)問題。, y4 P+ M" W& D- k; V( v
#error& M! R/ |/ n! U9 T0 ?. i
#error 是一種預(yù)編譯器指示字,用于生成一個(gè)編譯錯(cuò)誤消息 。用法:#error [message] //message為用戶自定義的錯(cuò)誤提示信息,可缺省。#error 可用于提示編譯條件是否滿足。編譯過程中的任何錯(cuò)誤意味著無法生成最終的可執(zhí)行程序。上面的程序優(yōu)化為#define PARA_STARADDR (0x08000+(100*1024)) //前100K用于存儲(chǔ)固件,參數(shù)存儲(chǔ)開始地址。#define FLASH_SECTOR_SIZE (2*1024) //Flash每個(gè)扇區(qū)的大小: d1 n2 w+ a$ w0 Q/ P
#define PARA_BATTERY_ADDR PARA_STARADDR //存儲(chǔ)電池參數(shù)#define PARA_BATTERY_SIZE (1*FLASH_SECTOR_SIZE) //電池參數(shù)所占空間大小
$ H7 Y8 ?; J2 t/ M+ ?9 a% P4 w0 \#define PARA_ETH_ADDR (PARA_BATTERY_ADDR+PARA_BATTERY_SIZE) //存儲(chǔ)網(wǎng)絡(luò)參數(shù)#define PARA_ETH_SIZE (2*FLASH_SECTOR_SIZE) //網(wǎng)絡(luò)參數(shù)所占空間大小
4 N2 Q0 ^' t" V( x) j' z+ `' t#define PARA_END_ADDR (PARA_ETH_ADDR+PARA_ETH_SIZE)// 參數(shù)的結(jié)束地址#if (PARA_END_ADDR > 0x0801E000) #error Flash Map Error#endif這樣當(dāng)你的參數(shù)最后地址大于0x0801E000,編譯器機(jī)會(huì)報(bào)錯(cuò),根本編譯不過,如下圖( r$ p* Y$ m# M. r3 l6 S0 Q
ofcxntodlo364014186733.png (2.75 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
ofcxntodlo364014186733.png
2024-9-1 11:48 上傳
' j6 J/ {$ q: n, x7 [/ g
類似的,#warning 用于生成編譯警告消息。warning可用來提示一些非致命錯(cuò)誤。
, D* h0 s: ]) c其他用法0 c' D& q. H4 I) [# S8 o
限定宏定義的數(shù)值范圍,下面SIZE被限制在0到100內(nèi)。
. s% ~! S+ w! r- N: b% w#define SIZE 10#if SIZE 100#error SIZE must be between 1 and 100.#endifuint8_t buffer[SIZE];指定使用VS編譯器
0 |5 f2 N* f6 O1 k#ifndef _MSC_VER#error require visual studio compiler#endif判斷是否定義了某個(gè)宏,比如FreeRTOS源碼中
& z, p5 S: m( j h( X z8 q, b5 x#ifndef configMINIMAL_STACK_SIZE #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value.#endifEND
- P4 N9 }) g% u8 a6 [
0sldhmf1v3t64014186833.gif (170.56 KB, 下載次數(shù): 1)
下載附件
保存到相冊(cè)
0sldhmf1v3t64014186833.gif
2024-9-1 11:48 上傳
: d8 M; o$ g$ h5 U
eifmxbjanuh64014186933.gif (66.66 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
eifmxbjanuh64014186933.gif
2024-9-1 11:48 上傳
8 X: n3 e c7 M O, k. f0 O1 m( i?指針與函數(shù): T4 S5 }6 @2 H5 K1 ^9 ], R
?聊聊數(shù)據(jù)溢出的事
+ T& T9 Y5 M, Z4 y, u" y, c6 V& u?MCU為什么內(nèi)部不集成晶振 必讀: a+ ]9 z; w1 l! y* D% y: w- [
?表驅(qū)動(dòng)法在STM32中的應(yīng)用+ [% k% H( f$ k$ U3 H$ y
?設(shè)計(jì)一款兼容ST207和GD207的開發(fā)板 必讀 |
|