0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是斷言函數(shù)呢?斷言函數(shù)在調(diào)試中的應(yīng)用

冬至子 ? 來(lái)源:聊點(diǎn)嵌入式 ? 作者:聊點(diǎn)嵌入式 ? 2023-11-06 15:55 ? 次閱讀

這一次我們繼續(xù)講調(diào)試方法。調(diào)試是排查程序Bug的有效方法,同時(shí)也對(duì)嵌入式軟件設(shè)計(jì)的可靠性、穩(wěn)定性而言至關(guān)重要。之前講的調(diào)試方法能夠打印出變量值、系統(tǒng)狀態(tài),或用互動(dòng)的方式去調(diào)試程序,都不能動(dòng)態(tài)的在系統(tǒng)運(yùn)行時(shí)由程序判斷變量、參數(shù)是否出錯(cuò)。

而我們今天要講的斷言(assert)函數(shù)則能做到在運(yùn)行時(shí)判斷參數(shù)是否超出預(yù)設(shè)值、狀態(tài)是否出錯(cuò),然后打印出出錯(cuò)數(shù)據(jù)所在的源文件和行號(hào)。

那么,什么是斷言函數(shù)呢?百度百科給的定義是:“斷言(assertion)是一種在程序中的一階邏輯(如:一個(gè)結(jié)果為真或假的邏輯判斷式),目的為了表示與驗(yàn)證軟件開(kāi)發(fā)者預(yù)期的結(jié)果——當(dāng)程序執(zhí)行到斷言的位置時(shí),對(duì)應(yīng)的斷言應(yīng)該為真。若斷言不為真時(shí),程序會(huì)中止執(zhí)行,并給出錯(cuò)誤信息。“

接下來(lái),我們繼續(xù)采用上一次實(shí)時(shí)跟蹤調(diào)試的例子,加入斷言函數(shù)對(duì)運(yùn)行過(guò)程的參數(shù)進(jìn)行判斷,看看斷言函數(shù)如何應(yīng)用,有什么效果。

1. CubeMX設(shè)置

我們可以在CubeMX中打開(kāi)例子工程中的.ioc文件,按下圖進(jìn)行設(shè)置。

圖片

除此之外,可以直接在CubeIDE的工程屬性里定義一個(gè)宏USE_FULL_ASSERT,也可以在工程任意頭文件中定義這個(gè)宏,效果是一樣的。其實(shí)采用CubeMX配置之后,就是在工程的stm2f7xx_hal_conf.h頭文件中定義了這個(gè)宏。

2. 修改代碼

當(dāng)定義了宏USE_FULL_ASSERT之后,assert_failed函數(shù)就能參與編譯了,這個(gè)函數(shù)在main.c的最下邊。這個(gè)函數(shù)的代碼如下:

void assert_failed(uint8_t *file, uint32_t line)
{
printf("Wrong parameters value: file %s on line %drn", file, (uint16_t)line);
}

斷言失敗的話則會(huì)執(zhí)行這個(gè)函數(shù),利用printf打印一條消息,這里我們用的是CubeIDE的ITM模塊向外打印,打印的消息里包含斷言失敗語(yǔ)句所在的源文件及行數(shù)。

要注意的是,參數(shù)line本來(lái)是無(wú)符號(hào)長(zhǎng)整形,printf函數(shù)用%d對(duì)應(yīng)長(zhǎng)整形的話會(huì)給警告,所以做了一個(gè)強(qiáng)制類(lèi)型轉(zhuǎn)換,變?yōu)闊o(wú)符號(hào)短整型。我想應(yīng)該不會(huì)有一個(gè)源文件超過(guò)65535行吧,那是要挨打的。

接下來(lái)在main.h里定義一個(gè)宏IS_PARA_COUNTER_OK,當(dāng)然名字可以自己任意取。

#define IS_PARA_COUNTER_OK(para) (para < 5)

這個(gè)宏的其實(shí)是個(gè)表達(dá)式,用以對(duì)para參數(shù)的值進(jìn)行判斷,這里假設(shè)para的值小于5是正常的。為了防止出錯(cuò),表達(dá)式用小括號(hào)括起來(lái)了。

在main函數(shù)while循環(huán)開(kāi)始的地方,我們加上一條語(yǔ)句,用來(lái)對(duì)我們?cè)O(shè)置的一個(gè)用來(lái)計(jì)數(shù)的變量counter進(jìn)行參數(shù)斷言。

assert_param(IS_PARA_COUNTER_OK(counter));

其中,assert_param是在stm2f7xx_hal_conf.h中定義的一個(gè)宏。

#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *) FILE , LINE ))

意思是當(dāng)expr表達(dá)式的值為真的時(shí)候,不執(zhí)行任何操作,為假時(shí),斷言失敗,執(zhí)行assert_failed函數(shù),并向該函數(shù)傳遞斷言失敗語(yǔ)句所在的源文件和行。__FILE__和__LINE__都是C語(yǔ)言定義的宏,分別代表當(dāng)前源文件和所在行。

我們?cè)趍ain函數(shù)中寫(xiě)的斷言語(yǔ)句可以完全展開(kāi)如下:

(((counter < 5)) ? (void)0U : assert_failed((uint8_t *)"D:workspaceSTM32F7example2_ITMCoreSrcmain.c", 101))

是的,這條語(yǔ)句位于main.c的101行。

3. 調(diào)試結(jié)果

代碼修改好后,連接好開(kāi)發(fā)板,構(gòu)建工程,進(jìn)入調(diào)試模式并開(kāi)始運(yùn)行,我們可以在SWV ITM Data Console窗口看到如下信息。

圖片

這里要說(shuō)明一下,代碼里counter值是在打印之后加1的,也就是說(shuō)在打印出4之后,其值已經(jīng)變?yōu)?,導(dǎo)致參數(shù)斷言出錯(cuò),打印出預(yù)設(shè)消息。另外我們也可以在assert_failed函數(shù)里加入一個(gè)死循環(huán),斷言失敗后程序就不會(huì)繼續(xù)往下執(zhí)行了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7608

    瀏覽量

    137110
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    492

    瀏覽量

    27574
  • HAL庫(kù)
    +關(guān)注

    關(guān)注

    1

    文章

    121

    瀏覽量

    6322
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    什么是斷言?C語(yǔ)言中斷言的語(yǔ)法和用法

    軟件開(kāi)發(fā)過(guò)程,我們經(jīng)常需要處理各種錯(cuò)誤和異常情況。為了提高代碼的健壯性和可靠性,我們需要使用一些工具和技術(shù)來(lái)檢測(cè)和處理這些問(wèn)題。本篇博客將深入探討C語(yǔ)言中斷言的使用,幫助讀者更好地理解和應(yīng)用
    發(fā)表于 08-03 10:34 ?2812次閱讀

    解析C語(yǔ)言斷言函數(shù)的使用

    對(duì)于斷言,相信大家都不陌生,大多數(shù)編程語(yǔ)言也都有斷言這一特性。簡(jiǎn)單地講,斷言就是對(duì)某種假設(shè)條件進(jìn)行檢查。 C 語(yǔ)言中,斷言被定義為宏的形
    發(fā)表于 08-08 09:51 ?491次閱讀
    解析C語(yǔ)言<b class='flag-5'>斷言</b><b class='flag-5'>函數(shù)</b>的使用

    何為斷言斷言的作用有哪些?斷言的種類(lèi) 斷言層次結(jié)構(gòu)

    斷言主要用來(lái)檢查仿真過(guò)程存在的時(shí)序問(wèn)題,如果存在異常情況,斷言會(huì)報(bào)警。一般在數(shù)字電路設(shè)計(jì)中都要加入斷言,斷言占整個(gè)設(shè)計(jì)的比例應(yīng)不少于30%
    的頭像 發(fā)表于 08-28 11:16 ?8477次閱讀
    何為<b class='flag-5'>斷言</b>?<b class='flag-5'>斷言</b>的作用有哪些?<b class='flag-5'>斷言</b>的種類(lèi) <b class='flag-5'>斷言</b>層次結(jié)構(gòu)

    C語(yǔ)言assert(斷言)簡(jiǎn)介

    assert的功能,條件為真,程序繼續(xù)執(zhí)行;如果斷言為假(false),則程序終止。
    的頭像 發(fā)表于 11-17 16:33 ?1178次閱讀
    C語(yǔ)言assert(<b class='flag-5'>斷言</b>)簡(jiǎn)介

    如何在XC8使用斷言的?

    大家好,我正在嘗試使用XC8斷言,但是當(dāng)我使用“*”時(shí),“斷言h”空格main(空隙){BOOL X=0;斷言(x= 1);而(1){}}我的程序停止,并且
    發(fā)表于 03-26 10:58

    ART-Pi調(diào)試LAN8720object初始化遇到斷言報(bào)錯(cuò)的原因是什么?

    使用rt-thread stdio平臺(tái)和ART-Pi開(kāi)發(fā)LAN8720A。目前已經(jīng)過(guò)了ETH的初始化,但是object.c的rt_object_init()初始化函數(shù)斷言報(bào)錯(cuò)。請(qǐng)教一下論壇的朋友
    發(fā)表于 04-14 09:42

    SVA斷言是基于邊沿還是電平?

    SVA斷言是一個(gè)強(qiáng)時(shí)序的技術(shù),很多時(shí)候SVA的實(shí)際時(shí)序和驗(yàn)證工程師的期望可能不同,這種不同很難調(diào)試定位。下面是一個(gè)SVA斷言的示例,驗(yàn)證工程師期望斷言當(dāng)檢測(cè)到req的上升沿后,再持續(xù)高
    發(fā)表于 08-25 15:57

    何為斷言斷言該怎么使用

    的每個(gè)函數(shù)的參數(shù)!調(diào)試的便利 :如果在程序測(cè)試和調(diào)試期間違反了前置條件,也就是說(shuō)斷言異常了,則調(diào)用包含前置條件的函數(shù)的代碼
    發(fā)表于 09-21 14:59

    怎樣去修復(fù)HAL_NVIC_SetPriority的斷言故障

    優(yōu)先級(jí)值HAL_NVIC_SetPriority 的 PreemptPriority 值 0-15 之間變化,但是當(dāng)調(diào)用 HAL_RCC_ClockConfig 函數(shù)時(shí),該值是 16。(最大 4 位
    發(fā)表于 12-12 07:17

    SystemVerilog斷言及其應(yīng)用

    介紹SystemVerilog 斷言的概念、使用斷言的好處、斷言的分類(lèi)、斷言的組成以及斷言如何
    發(fā)表于 05-24 16:35 ?0次下載
    SystemVerilog<b class='flag-5'>斷言</b>及其應(yīng)用

    怎么理解Assert斷言語(yǔ)句?

    為什么項(xiàng)目中的代碼需要有Assert斷言語(yǔ)句?
    的頭像 發(fā)表于 03-03 14:12 ?2758次閱讀

    STM32函數(shù)庫(kù)Assert斷言機(jī)制

    編寫(xiě)代碼時(shí),我們總是會(huì)做出一些假設(shè),斷言就是用于代碼捕捉這些假設(shè),可以將斷言看作是異常處理的一種高級(jí)形式。斷言表示為一些布爾表達(dá)式,程序
    發(fā)表于 02-08 15:29 ?2次下載
    STM32<b class='flag-5'>函數(shù)</b>庫(kù)Assert<b class='flag-5'>斷言</b>機(jī)制

    C語(yǔ)言斷言函數(shù)assert()的應(yīng)用,清晰明了!

    這樣可以快速發(fā)現(xiàn)并定位軟件問(wèn)題,同時(shí)對(duì)系統(tǒng)錯(cuò)誤進(jìn)行自動(dòng)報(bào)警。對(duì)于系統(tǒng)隱藏很深,用其他手段極難發(fā)現(xiàn)的問(wèn)題也可以通過(guò)斷言進(jìn)行定位,從而縮短軟件問(wèn)題定位時(shí)間,提高系統(tǒng)的可測(cè)性。
    的頭像 發(fā)表于 04-12 10:02 ?1126次閱讀

    防御式編程之斷言assert的使用

    防御式編程的重點(diǎn)就是需要防御一些程序未曾預(yù)料的錯(cuò)誤,這是一種提高軟件質(zhì)量的輔助性方法,斷言assert就用于防御式編程,編寫(xiě)代碼時(shí),我們總是會(huì)做出一些假設(shè),斷言就是用于代碼捕捉這些
    的頭像 發(fā)表于 04-19 11:35 ?689次閱讀

    基于斷言的驗(yàn)證簡(jiǎn)介 – 第 1 部分

    基于斷言的驗(yàn)證(ABV)是一種與傳統(tǒng)方法相比可以大大減少驗(yàn)證過(guò)程的技術(shù).
    的頭像 發(fā)表于 01-09 09:59 ?607次閱讀
    基于<b class='flag-5'>斷言</b>的驗(yàn)證簡(jiǎn)介 – 第 1 部分