<dfn id="is4kg"></dfn>
  • <ul id="is4kg"></ul>
  • <abbr id="is4kg"></abbr>
  • <ul id="is4kg"></ul>
    <bdo id="is4kg"></bdo>

    曙海教育集團(tuán)論壇Linux專(zhuān)區(qū)Linux系統(tǒng)開(kāi)發(fā) → 在Linux下用Gcc 4.3.1進(jìn)行STM32開(kāi)發(fā)入門(mén)


      共有7185人關(guān)注過(guò)本帖樹(shù)形打印

    主題:在Linux下用Gcc 4.3.1進(jìn)行STM32開(kāi)發(fā)入門(mén)

    美女呀,離線,留言給我吧!
    wangxinxin
      1樓 個(gè)性首頁(yè) | 博客 | 信息 | 搜索 | 郵箱 | 主頁(yè) | UC


    加好友 發(fā)短信
    等級(jí):青蜂俠 帖子:1393 積分:14038 威望:0 精華:0 注冊(cè):2010-11-12 11:08:23
    在Linux下用Gcc 4.3.1進(jìn)行STM32開(kāi)發(fā)入門(mén)  發(fā)帖心情 Post By:2010-11-25 10:10:27

    今天,嘗試了在我使用的Gentoo系統(tǒng)上位Cortex-m3構(gòu)建GNU工具鏈,沒(méi)想到如此簡(jiǎn)單。
    以超級(jí)用戶(hù)權(quán)限運(yùn)行如下命令:
    crossdev --g 4.3.1-r1 -t arm-elf
    因?yàn)楣俜降膅cc在4.3版本下加入了對(duì)cortex-m3的支持,所以上面的命令用 --g 4.3.1-r1參數(shù),指定了4.3.1-r1版的GCC。整個(gè)編譯過(guò)程非常順利,編譯成功后得到了:arm-elf-gcc,arm-elf- ld,arm-elf-objcopy等命令,這些就是所需要的工具。

    參考
    1、
    大俠 bozai 章其波 在
    [原創(chuàng)] 支持cortex-M3 的GNU ARM編譯器 CodeSourcery 上的第一個(gè)STM32F10x例子
    http://www.ouravr.com/bbs/bbs_li ... 1&bbs_page_no=2
    一帖中給出的工程(makefile和ldscripts)

    2、大俠bluelucky翻譯的《Cortex-M3權(quán)威指南》中有關(guān)用gcc進(jìn)行開(kāi)發(fā)的章節(jié)。

    寫(xiě)了一個(gè)簡(jiǎn)單的程序,經(jīng)測(cè)試成功的點(diǎn)亮了LED。

    所有心得不敢獨(dú)享,在這里與大家分享一下,一并謝謝bluelucky和章其波的辛勤勞作。

    -------------------------------------------------------------------------------------------------------------------------------------

    一、安裝GNU工具鏈
    因?yàn)樵贕entoo Linux下有crossdev這個(gè)非常強(qiáng)大的構(gòu)建交叉編譯工具鏈的工具,安裝Cortex-m3的交叉工具鏈非常簡(jiǎn)單,方法前以述及,這里不贅述。

    二、STM32F10x(Cortex-m3)基于GNU工具鏈的開(kāi)發(fā)流程

    《Cortex-M3權(quán)威指南》一書(shū)中有如下這個(gè)開(kāi)發(fā)流程圖:

    由圖可知,用C語(yǔ)言進(jìn)行stm32的程序開(kāi)發(fā),仍然是:寫(xiě)代碼--->編譯、連接--->下載到flash這樣一個(gè)過(guò)程。只不過(guò)除此以外,我認(rèn)為比較重要的還需要知道這樣幾點(diǎn):
    1、如何訪問(wèn)此種單片機(jī)的外圍設(shè)備寄存器;
    2、如何書(shū)寫(xiě)此種單片機(jī)的中斷服務(wù)程序;
    3、此種單片機(jī)復(fù)位后,從什么地址處開(kāi)始執(zhí)行代碼;然后我們?nèi)绾胃嬖V編譯工具把代碼按照這個(gè)入口地址開(kāi)始安排我們的代碼。
    4、需不需要為構(gòu)建C語(yǔ)言的運(yùn)行環(huán)境作一些工作,也就是啟動(dòng)代碼。
    5、通過(guò)命令行選項(xiàng)通知編譯器為特定的單片機(jī)生成代碼。

    三、編寫(xiě)一個(gè)最精簡(jiǎn)的代碼

    1、一個(gè)main函數(shù)就足夠了嗎?

    先讓我們簡(jiǎn)單回顧一下在PC機(jī),一個(gè)程序的執(zhí)行過(guò)程大概是怎樣的。因?yàn)槌绦蚴窃诓僮飨到y(tǒng)的管理下運(yùn)行的,過(guò)程大概為:

    操作系統(tǒng)----------> 啟動(dòng)代碼(編譯器自動(dòng)加入,做一些堆棧、全局變量的初始化工作)-----------> main

    然而在裸奔的單片機(jī)上,操作系統(tǒng)沒(méi)有了,所以原來(lái)由操作系統(tǒng)和編譯器作的事情,現(xiàn)在需要我們手工DIY了(如果交叉編譯工具沒(méi)有為我們做好這些事情的話,因?yàn)槲乙膊恢纆cc現(xiàn)在有沒(méi)有為stm32做好這一切,所以我暫時(shí)假定什么都得靠自己)。

    2、C程序的典型內(nèi)存布局

                +-------------------------------+
                |                               |
                |            堆棧               |
                |                               |
                + - - - - - - - - - - - - - - - +
                |                               |
                |                               |
                |                               |
                |                               |
                |                               |
                |                               |
                |                               |
                |                               |
                |                               |
                + - - - - - - - - - - - - - - - +
                |                               |
                |             堆                |
                |                               |
                +-------------------------------+
                |                               |
                |        未初始化的數(shù)據(jù)         |
                |           .bss段              |
                |                               |
                +-------------------------------+
                |                               |
                |         初始化的數(shù)據(jù)          |
                |           .data段             |
                |                               |
                +-------------------------------+
                |                               |
                |            正文               |           
                |           .text段             |
                |          .rodata段            |
                |                               |
                +-------------------------------+

    上圖中,正文對(duì)應(yīng)的是可執(zhí)行代碼.text和常量表格數(shù)據(jù)等.rodata,.data對(duì)應(yīng)初始化了的全局變量,編譯后將位于可執(zhí)行文件中,由啟動(dòng)代碼負(fù)責(zé)加載到數(shù)據(jù)區(qū)中(在單片機(jī)中這部分?jǐn)?shù)據(jù)會(huì)存于flash中,需要有啟動(dòng)代碼把這部分內(nèi)容拷貝到sram中),.bss段是沒(méi)有初始值的全局變量,由啟動(dòng)代碼把這部分內(nèi)容全初始化為0;為了保證C程序的執(zhí)行,還需要設(shè)置好程序運(yùn)行時(shí)的堆棧區(qū)。

    在有了這些基礎(chǔ)知識(shí)后,除了main以外,我們還需要做些什么就比較清楚了:設(shè)置堆棧區(qū),把編譯好的內(nèi)容放到單片機(jī)中正確的地方中去。


    3、設(shè)置堆棧區(qū)和啟動(dòng)代碼

    Cortex-m3內(nèi)核在地址0x0000 0000處存放一個(gè)向量表,向量表的第0個(gè)單元,也即地址0x0000 0000處存放的是堆棧頂?shù)牡刂罚珻ortex-m3復(fù)位后即從該處取出數(shù)據(jù)用以初始化MSP寄存器。向量表中的內(nèi)容是32位的地址,這些地址是中斷異常服務(wù)程序的入口地址,其中向量表的第一個(gè)單元,即地址0x0000 0004處存放的是復(fù)位向量,也就是說(shuō)Cortex-m3復(fù)位后,執(zhí)行該向量(可理解為函數(shù)指針)指向的復(fù)位代碼。看看代碼吧:

    __attribute__ ((section(".stackarea")))
    static unsigned long pulStack[STACK_SIZE];
    這一句定義了一個(gè)pulStack的數(shù)組,程序把這個(gè)數(shù)組作為了堆棧區(qū)。這條語(yǔ)句使用了__attribute__ ((section(".stackarea"))) 把數(shù)組定位在了.stackarea這個(gè)段中。

    typedef void (* pfnISR)(void);

    __attribute__ ((section(".isr_vector")))
    pfnISR        VectorTable[] =  
    {

            (pfnISR)((unsigned long)pulStack + sizeof(pulStack)),        // The initial stack pointer
            ResetISR,                                               // The reset handler
            NMIException,
            HardFaultException
    };

    定義了一個(gè)數(shù)組VectorTable,作為向量表,定位于.isr_vector段中。通過(guò)鏈接腳本的控制這個(gè)表將放在正文區(qū)的最開(kāi)始,正文區(qū)又將從flash的最開(kāi)始存放,這樣這個(gè)向量表就會(huì)起到相當(dāng)于存放在0x0000 0000開(kāi)始的地址空間的效果。
    向量表的第0個(gè)單元是((unsigned long)pulStack + sizeof(pulStack)),這是數(shù)組的最后一個(gè)元素,因?yàn)镃ortex-m3的堆棧是向下增長(zhǎng)的。
    向量表的第1個(gè)單元是ResetISR,它指向復(fù)位處理的代碼,也是整個(gè)程序的入口。本程序用它來(lái)實(shí)現(xiàn)啟動(dòng)代碼的功能。

    extern unsigned long _etext;
    extern unsigned long _data;
    extern unsigned long _edata;
    extern unsigned long _bss;
    extern unsigned long _ebss;

    void ResetISR(void)
    {
            unsigned long *pulSrc, *pulDest;

            //
            // Copy the data segment initializers from flash to SRAM.
            //
            pulSrc = &_etext;
            for(pulDest = &_data; pulDest < &_edata; )
            {
                    *pulDest++ = *pulSrc++;
            }

            //
            // Zero fill the bss segment.
            //
            for(pulDest = &_bss; pulDest < &_ebss; )
            {
                    *pulDest++ = 0;
            }

            //
            // Call the application's entry point.
            //
            main();
    }
    這段代碼用到了通過(guò)連接器賦值的幾個(gè)變量值。_etext的值為正文段結(jié)尾處的地址,這之后的flash空間是初始化的數(shù)據(jù)值,應(yīng)該復(fù)制到sram中去,
    _data、_edata的值分別為數(shù)據(jù)段的開(kāi)始和結(jié)尾處的地址,這部分應(yīng)該是sram的地址。

            pulSrc = &_etext;
            for(pulDest = &_data; pulDest < &_edata; )
            {
                    *pulDest++ = *pulSrc++;
            }
    這部分代碼就是將保存于flash中的初始化數(shù)據(jù)復(fù)制到sram中。
    上面代碼中的第二個(gè)循環(huán)是將.bss段清零。最后調(diào)用main進(jìn)入到我們的主程序。

    支持(0中立(0反對(duì)(0單帖管理 | 引用 | 回復(fù) 回到頂部

    返回版面帖子列表

    在Linux下用Gcc 4.3.1進(jìn)行STM32開(kāi)發(fā)入門(mén)








    簽名
    主站蜘蛛池模板: a级毛片免费网站| 亚洲欧美在线播放| 香港三日本8A三级少妇三级99| 影音先锋人妻啪啪av资源网站 | 啊快捣烂了啦h男男开荤粗漫画 | 日韩欧美国产高清| 亚洲自偷自拍另类图片二区| 综合激情网五月| 国产最新凸凹视频免费| chinese国产高清av内谢| 成人欧美一区二区三区的电影 | 菠萝蜜视频在线观看免费视频| 国产精品视频白浆免费视频| 中文字幕a∨在线乱码免费看| 日本视频网站在线www色| 亚洲欧美中文日韩在线| 男人j放进女人j网站免费| 国产三香港三韩国三级不卡 | 亚洲国产AV一区二区三区四区 | 久久亚洲精品无码gv| 朝鲜女人性猛交| 亚洲综合欧美日韩| 男女性杂交内射女BBWXZ| 国产三级在线观看| 韩国爱情电影妈妈的朋友 | 在现免费看的www视频的软件| 中文字幕日韩哦哦哦| 日本精品在线观看视频| 亚洲国产成人久久综合一区77 | 护士好爽好深好多水| 亚洲欧美精品一中文字幕| 狠狠色成人综合首页| 国产gaysexchina男同menxnxx| 风间由美性色一区二区三区 | 天天做天天添天天谢| 久久99久久99精品免观看| 日韩三级电影院| 亚洲国产小视频| 欧美性白人极品hd| 亚洲高清美女一区二区三区| 男彩虹用的app小蓝|