真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

嵌入式C語言自我修養(yǎng)13:總結(jié)

13.1 總結(jié)

前面12節(jié)的課程,主要針對 Linux 內(nèi)核中 GNU C 擴(kuò)展的一些常用 C 語言語法進(jìn)行了分析。GNU C 的這些擴(kuò)展語法,主要用來完善 C 語言標(biāo)準(zhǔn)和編譯優(yōu)化。而通過 C 標(biāo)準(zhǔn)的發(fā)展過程我們又發(fā)現(xiàn),對于一些編譯器擴(kuò)展的一些特性,或者其它編程語言(如:C++)中的好的特性和語法,C 標(biāo)準(zhǔn)也會適時地吸收進(jìn)來,作為新的 C 語言標(biāo)準(zhǔn)。

專注于為中小企業(yè)提供成都做網(wǎng)站、成都網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)內(nèi)黃免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上千余家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

在 GNU C 的這些擴(kuò)展語法中,attribute和宏定義是兩大特色。在嵌入式底層系統(tǒng)中,尤其是 Linux 內(nèi)核和 U-boot 中,大量使用 GNU C 擴(kuò)展的 attribute屬性去輔助一些底層機(jī)制的實(shí)現(xiàn),或者實(shí)現(xiàn)一些編譯上的優(yōu)化。在宏定義方面,通過語句表達(dá)式、可變參數(shù)宏等特性,我們可以定義一個功能復(fù)雜、安全可靠的高質(zhì)量宏。

本教程所講的一些特性,都是在實(shí)際工作或閱讀 Linux 內(nèi)核驅(qū)動源碼時經(jīng)常遇見的一些特性,掌握了這些擴(kuò)展特性的使用,以后再遇到類似的“奇葩 C 語言”程序,就知道怎么去分析了。除此之外,GNU C 還有一些其它擴(kuò)展特性,由于他們在內(nèi)核中用得不是很多,或者說僅僅是做一些編譯上的優(yōu)化,即使不知道也不會影響我們理解代碼,限于篇幅關(guān)系,所以就暫時不講了,比如下面這些特性。

  • 屬性聲明:const
  • 屬性聲明:constructor、destructor
  • 屬性聲明:noreturn
  • 屬性聲明:used、unused
  • 局部標(biāo)簽
  • 嵌套函數(shù)
  • ……

大家以后遇到類似的擴(kuò)展,可以到下面這幾個網(wǎng)站上去看看。

  • GNU C語法擴(kuò)展大全
  • GCC 編譯器手冊

13.2 C 語言習(xí)題測試

下面是幾道 C 語言練習(xí)題,大家可以做一做??纯磳W(xué)完本教程后,有沒有真正的掌握。有什么疑問,可以通過讀者圈,或加入QQ群(475504428)與我討論。

1.下面的程序,在不同編譯環(huán)境下,比如分別在 C-Free、VC++6.0、TurboC 環(huán)境下編譯運(yùn)行,結(jié)果是否相等,為什么?

#include
int main(void)
{
    printf("size: %d\n", sizeof(int);
    return 0;
}

2.定義一個宏,求兩個數(shù)的最小值。

3.將下面的程序編譯為可以在 ARM 平臺上運(yùn)行的可執(zhí)行文件 a.out,并對其進(jìn)行反匯編,查看變量 global_val 的地址。

int global_val = 10;
int uninit_val;
int main(void)
{
    int local_val = 20;
    return 0;
}
  1. 在一個工程項(xiàng)目中,有兩個源文件如下,分析下面程序的運(yùn)行結(jié)果。

    //func.c
    int a = 10;
    int b;
    int c attribute((weak)) = 30;

    //main.c
    int a;
    int b = 20;
    int c = 40;
    int main(void)
    {
    printf("a: %d\n",a);
    printf("b: %d\n",b);
    printf("c: %d\n",c);
    return 0;
    }

5.定義一個變參函數(shù),實(shí)現(xiàn)等級打印控制:ERROR、DEBUG、INFO。用這三個宏分別代表等級打印,比如定義 ERROR 時,只打印錯誤的信息;定義 DEBUG 時,打印錯誤和調(diào)試信息;定義 INFO 時,所有的打印信息都打印出來。

6.定義一個變參宏,實(shí)現(xiàn)等級打印控制:ERROR、DEBUG、INFO。用這三個宏分別代表等級打印,比如定義 ERROR 宏時,只打印錯誤的信息;定義 DEBUG 時,打印錯誤和調(diào)試信息;定義 INFO 時,所有的打印信息都打印出來。

7.下面是 Linux 內(nèi)核(Linux4.4.0)中的一些宏定義,請分析它們實(shí)現(xiàn)的功能。

#define pr_emerg(fmt, ...) \
    printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
#define pr_alert(fmt, ...) \
    printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
#define pr_crit(fmt, ...) \
    printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
#define pr_err(fmt, ...) \
    printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
#define pr_warning(fmt, ...) \
    printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
#define pr_warn pr_warning
#define pr_notice(fmt, ...) \
    printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
#define pr_info(fmt, ...) \
    printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)

8.在 Linux 內(nèi)核啟動過程中,啟動 log 的最后往往會有這么一行信息。

Freeing unused kernel memory: 468K

請用本課程中的 section 屬性聲明,分析這段 log 背后的內(nèi)核初始化及內(nèi)存釋放過程。

9.在嵌入式 Linux 驅(qū)動開發(fā)中,驅(qū)動模塊是沒有 main() 入口函數(shù)的,請用本課程學(xué)過的知識分析:驅(qū)動是如何運(yùn)行和初始化的。

10.驅(qū)動分析:在 linux4.4 源碼 linux-4.4/arch/arm/mach-footbridge/ebsa285.c 中,分析下面代碼的含義及 container_of 宏的作用。

MACHINE_START(EBSA285, "EBSA285")
    /* Maintainer: Russell King */
    .atag_offset    = 0x100,
    .video_start    = 0x000a0000,
    .video_end  = 0x000bffff,
    .map_io     = footbridge_map_io,
    .init_early = footbridge_sched_clock,
    .init_irq   = footbridge_init_irq,
    .init_time  = footbridge_timer_init,
    .restart    = footbridge_restart,
MACHINE_END
static void ebsa285_led_set(struct \
led_classdev *cdev, enum led_brightness b)
{
    struct ebsa285_led *led = container_of(cdev,
            struct ebsa285_led, cdev);

    if (b == LED_OFF)
        hw_led_state |= led->mask;
    else
        hw_led_state &= ~led->mask;
    writeb(hw_led_state, xbus);
}

static enum led_brightness \
ebsa285_led_get(struct led_classdev *cdev)
{
    struct ebsa285_led *led = container_of(cdev,
            struct ebsa285_led, cdev);

    return hw_led_state & led->mask ? LED_OFF : LED_FULL;
}

13.3 結(jié)束語

通過本課程的學(xué)習(xí),再加上本節(jié)10個習(xí)題的練習(xí),相信大家的 C 語言功底肯定又加深了一層!有了這些知識儲備基礎(chǔ),基本上就掃除了 Linux 內(nèi)核的閱讀障礙。相信大家在以后的工作、學(xué)習(xí)中一定會日益精進(jìn),不斷突破!

最后祝大家工作順利、學(xué)習(xí)愉快!

另外,大家如果想系統(tǒng)學(xué)習(xí) Linux 內(nèi)核中的某塊知識,或者說有哪些知識掌握得不是很好,想進(jìn)階學(xué)習(xí),但限于工作、學(xué)習(xí)繁忙,時間精力有限,無法系統(tǒng)地去學(xué)習(xí),也可以跟我聯(lián)系交流

  • 我的QQ:3284757626)
  • 我的博客:www.zhaixue.cc
  • 我會繼續(xù)編寫相關(guān)的的知識和教程,為大家服務(wù)。

本教程根據(jù) C語言嵌入式Linux高級編程視頻教程 第05期 改編,電子版書籍可加入QQ群:475504428 下載,更多嵌入式視頻教程,可關(guān)注:
微信公眾號:宅學(xué)部落(armlinuxfun)
51CTO學(xué)院-王利濤老師:http://edu.51cto.com/sd/d344f


文章標(biāo)題:嵌入式C語言自我修養(yǎng)13:總結(jié)
轉(zhuǎn)載來源:http://weahome.cn/article/pddiog.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部