日韩一区二区三区精品,欧美疯狂xxxxbbbb牲交,热99re久久免费视精品频,人妻互换 综合,欧美激情肉欲高潮视频

歷史上的今天

今天是:2025年07月08日(星期二)

2019年07月08日 | STM32F103+RTT從零開始(二)——RTT系統(tǒng)中點(diǎn)亮LED

發(fā)布者:BeaLaity0170 來源: eefocus關(guān)鍵字:STM32F103  RTT系統(tǒng)  點(diǎn)亮LED 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

上一篇博客簡單說了下如何使用Keil創(chuàng)建STM32F103的工程,并且完成了LED點(diǎn)亮,及讓LED等閃爍的功能,那是諸多同學(xué)學(xué)習(xí)單片機(jī)的起手式。本篇博客繼續(xù)上一篇博客的內(nèi)容,依舊是點(diǎn)亮LED,不同的是,這次點(diǎn)亮LED等,是在RT-Thread操作系統(tǒng)中進(jìn)行的。


創(chuàng)建工程

創(chuàng)建一個(gè)Keil工程,芯片依舊選擇STM32F103C8T6,然后在Manage Run-Time Environment對(duì)話框中選擇需要用的的軟件組件,與上文不同的是,我們需要把RTT一起勾上。如下圖: 

這里寫圖片描述


上圖中,紅線框中即為RTT操作系統(tǒng)的組件,分別為設(shè)備驅(qū)動(dòng),系統(tǒng)內(nèi)核以及shell。藍(lán)線框中為Keil的RTX操作系統(tǒng)。我們現(xiàn)在要用的是RTT,所以勾選RTT的組件即可,其中Kernel為必選項(xiàng),device drivers依賴kernel,shell又依賴device drivers。


shell也提一下,shell強(qiáng)翻成中文就是命令行外殼,如同linux操作系統(tǒng)一樣,RTT也提供了一套共用戶在命令行操作的操作接口。RTT提供的這套接口叫做finsh,主要用于調(diào)試、查看系統(tǒng)信息。finsh支持兩種模式:1. C語言解釋器模式, 為行文方便稱之為c-style;2. 傳統(tǒng)命令行模式,此模式又稱為msh(module shell)。 

在大部分嵌入式系統(tǒng)中,一般開發(fā)調(diào)試都使用硬件調(diào)試器和printf日志打印,在有些情況下,這兩種方式并不是那么好用。比如對(duì)于RT-Thread這個(gè)多線程系統(tǒng),我們想知道某個(gè)時(shí)刻系統(tǒng)中的線程運(yùn)行狀態(tài)、手動(dòng)控制系統(tǒng)狀態(tài)。如果有一個(gè)shell,就可以輸入命令,直接相應(yīng)的函數(shù)執(zhí)行獲得需要的信息,或者控制程序的行為。這無疑會(huì)非常方便。finsh就是基于此而設(shè)計(jì),它運(yùn)行于開發(fā)板,可以使用串口/以太網(wǎng)/USB等與PC機(jī)進(jìn)行通信。


創(chuàng)建工程后,相對(duì)上一篇博客創(chuàng)建的工程,項(xiàng)目中會(huì)多出了RTT,如下圖。至于各個(gè)文件及其作用,后續(xù)使用的時(shí)候再逐步理解。我們當(dāng)前最需要關(guān)注的是board.c和rtthread.h兩個(gè)文件。從圖中可以看出,只有這兩個(gè)文件上沒有標(biāo)注鑰匙,有鑰匙標(biāo)注的是不允許更改,也就是我們能更改就是這兩個(gè)文件。后面再分析這兩個(gè)文件。且走下一步。 


這里寫圖片描述

編寫點(diǎn)燈程序

創(chuàng)建好工程后,開始編寫點(diǎn)燈程序了,與上篇博客一樣,直接貼上代碼:


#include "rtthread.h"

#include "stm32f10x.h"

#include "stm32f10x_gpio.h"


int main(){


    GPIO_InitTypeDef gpioInit;


    //打開GPIOB的時(shí)鐘

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    //LED上拉連接GPIOB 12引腳,所以設(shè)置如下,推挽輸出,Pin12,2MHz輸出速度

    gpioInit.GPIO_Mode=GPIO_Mode_Out_PP;

    gpioInit.GPIO_Pin=GPIO_Pin_12;

    gpioInit.GPIO_Speed=GPIO_Speed_2MHz;

    GPIO_Init(GPIOB,&gpioInit);


    while(1){

        //點(diǎn)亮LED

        GPIO_ResetBits(GPIOB,GPIO_Pin_12);

        //延時(shí)0.5s

        rt_thread_delay(RT_TICK_PER_SECOND/2);

        //關(guān)閉LED

        GPIO_SetBits(GPIOB,GPIO_Pin_12);

        //延時(shí)0.5s

        rt_thread_delay(RT_TICK_PER_SECOND/2);

    }

}


這樣編寫程序后,編譯通過,燒寫后卻發(fā)現(xiàn)LED根本無法按照預(yù)期進(jìn)行工作,這是因?yàn)槲覀冞€缺少工作沒有做。 

打開board.c,可以看到它上面有幾句注釋,根據(jù)注釋,修改如下:


#include

#include

#include "stm32f10x_rcc.h"


// rtthread tick configuration

// 1. include header files

// 2. configure rtos tick and interrupt

// 3. add tick interrupt handler


// rtthread tick configuration

// 1. include some header file as need

//#include


#ifdef __CC_ARM

extern int Image$$RW_IRAM1$$ZI$$Limit;

#define HEAP_BEGIN    (&Image$$RW_IRAM1$$ZI$$Limit)

#elif __ICCARM__

#pragma section="HEAP"

#define HEAP_BEGIN    (__segment_end("HEAP"))

#else

extern int __bss_end;

#define HEAP_BEGIN    (&__bss_end)

#endif


#define SRAM_SIZE         8

#define SRAM_END          (0x20000000 + SRAM_SIZE * 1024)



/**

 * This function will initial STM32 board.

 */

void rt_hw_board_init()

{    

    // rtthread tick configuration

    // 2. Configure rtos tick and interrupt

    //SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);

    SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);

    /* Call components board initial (use INIT_BOARD_EXPORT()) */

#ifdef RT_USING_COMPONENTS_INIT

    rt_components_board_init();

#endif


#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)

    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);

#endif


#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)

    rt_system_heap_init((void*)HEAP_BEGIN, (void*)SRAM_END);

#endif

}


// rtthread tick configuration

// 3. add tick interrupt handler 

// tickvoid SysTick_Handler(void)

// {

//  /* enter interrupt */

//  rt_interrupt_enter();

// 

//  rt_tick_increase();

// 

//  /* leave interrupt */

//  rt_interrupt_leave();

// }


void SysTick_Handler(void)

{

//  /* enter interrupt */

rt_interrupt_enter();

// 

rt_tick_increase();

// 

//  /* leave interrupt */

rt_interrupt_leave();

}


再次編譯,燒寫程序,LED開始閃爍。


RTT第一次分析

board.c修改后,程序就正常工作了??墒菫槭裁茨兀扛鶕?jù)經(jīng)驗(yàn)來說,C程序不是從main開始的么,board中的程序又是何時(shí)執(zhí)行的呢?在main中我們有死循環(huán),如果是從main開始執(zhí)行的,那么board.c的函數(shù)就絕對(duì)不可能執(zhí)行了。


為什么不是從main開始執(zhí)行的

Ctrl+F搜索rt_hw_board_init函數(shù)。發(fā)現(xiàn)他在components.c中的rtthread_startup調(diào)用,再搜索rtthread_startup結(jié)構(gòu)發(fā)現(xiàn)其調(diào)用如下:


#if defined (__CC_ARM)

extern int $Super$$main(void);

/* re-define main function */

int $Sub$$main(void)

{

    rt_hw_interrupt_disable();

    rtthread_startup();

    return 0;

}

#elif defined(__ICCARM__)

extern int main(void);

/* __low_level_init will auto called by IAR cstartup */

extern void __iar_data_init3( void );

int __low_level_init(void)

{

    // call IAR table copy function.

    __iar_data_init3();

    rt_hw_interrupt_disable();

    rtthread_startup();

    return 0;

}

#elif defined(__GNUC__)

extern int main(void);

/* Add -eentry to arm-none-eabi-gcc argument */

int entry(void)

{

    rt_hw_interrupt_disable();

    rtthread_startup();

    return 0;

}

#endif



在上面預(yù)處理指令有三段,分別判斷三個(gè)宏是否被定義——__CC_ARM、__ICCARM__、__GNUC__,這三個(gè)是什么呢?如果全局搜索,會(huì)發(fā)現(xiàn)在core_cm3.h中它們出現(xiàn)很多次了。 

ARM 系列目前支持三大主流的工具鏈,即ARM RealView (armcc), IAR EWARM (iccarm), and GNU Compler Collection (gcc),這三個(gè)就是用來指示當(dāng)前使用的是哪個(gè)工具鏈。因?yàn)槲覀兪褂玫木褪荝ealView(Keil)了。 

可以看到$Super$$main和$Sub$$main,這又是什么呢? 

在某些情況下,無法修改現(xiàn)有符號(hào),例如,由于符號(hào)位于外部庫或 ROM 代碼中。為了解決這個(gè)問題,Keil提供了使用 $Super$$ 和 $Sub$$ 模式來修補(bǔ)現(xiàn)有符號(hào)的方法。 $Super$$標(biāo)識(shí)的是原函數(shù), $Sub$$標(biāo)識(shí)的是新函數(shù)。上面的代碼就是它們用法的最好示例了。


extern int $Super$$main(void);

/* re-define main function */

int $Sub$$main(void)

{

    rt_hw_interrupt_disable();

    rtthread_startup();

    return 0;

}


這樣,程序的執(zhí)行就不是從用戶寫的main方法開始了。而是從這個(gè)$Sub$$main(void)開始的了。


main是怎么執(zhí)行的

已經(jīng)知道了程序不是從main開始執(zhí)行的是RTT系統(tǒng)作的怪,那么用戶寫的main方法是何時(shí)執(zhí)行的呢?接著搜索$Super$$main,得到其調(diào)用如下:


/* the system main thread */

void main_thread_entry(void *parameter)

{

    extern int main(void);

    extern int $Super$$main(void);


    /* RT-Thread components initialization */

    rt_components_init();


    /* invoke system main function */

#if defined (__CC_ARM)

    $Super$$main(); /* for ARMCC. */

#elif defined(__ICCARM__) || defined(__GNUC__)

    main();

#endif

}


接著搜索main_thread_entry得帶代碼如下:


void rt_application_init(void)

{

    rt_thread_t tid;


#ifdef RT_USING_HEAP

    tid = rt_thread_create("main", main_thread_entry, RT_NULL,

                           RT_MAIN_THREAD_STACK_SIZE, RT_THREAD_PRIORITY_MAX / 3, 20);

    RT_ASSERT(tid != RT_NULL);

#else

    rt_err_t result;


    tid = &main_thread;

    result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,

                            main_stack, sizeof(main_stack), RT_THREAD_PRIORITY_MAX / 3, 20);

    RT_ASSERT(result == RT_EOK);

#endif


    rt_thread_startup(tid);

}


從名字就可以看得出來,這是在造線程啊,查閱下rtthread的官方文檔果然如此。rt_application_init被rtthread_startup調(diào)用,然后它創(chuàng)建了一個(gè)線程,并在線程中調(diào)用了用戶定義的main函數(shù)。至此就真相大白了。RTT利用工具鏈提供的方式,替換掉了用戶的main,來啟動(dòng)操作系統(tǒng),并創(chuàng)建了一條線程,在線程中調(diào)用了用戶的main方法。


至此,RTT操作系統(tǒng)就已經(jīng)在STM32C8T6核心板上跑起來了。后續(xù)使用RTT操作系統(tǒng)得先看下官方文檔,然后在使用中實(shí)踐,在實(shí)踐中深入理解,以便更快更好的掌握RTT。

關(guān)鍵字:STM32F103  RTT系統(tǒng)  點(diǎn)亮LED 引用地址:STM32F103+RTT從零開始(二)——RTT系統(tǒng)中點(diǎn)亮LED

上一篇:STM32F103+RTT從零開始(一)——點(diǎn)亮LED
下一篇:STM32使用標(biāo)準(zhǔn)庫,有時(shí)候在SLEEP模式下無法喚醒問題

推薦閱讀

小時(shí)候朋友常常擔(dān)心,等到長大之后,滿大街都是機(jī)器人,公司再也不招收了勞動(dòng)力,到哪個(gè)時(shí)候自己也就沒有工作可以做。機(jī)器人實(shí)在太厲害,現(xiàn)在許多地方都比人類強(qiáng),像家用機(jī)器人已經(jīng)自己在家掃地,工作完之后自己躲在墻角睡覺,比孩子還聽話。 是機(jī)器人核心部件,現(xiàn)在計(jì)算機(jī)處理能力已經(jīng)是非???。在2003年的時(shí)候,中國許多鄉(xiāng)鎮(zhèn)學(xué)校用的是電腦臺(tái)式機(jī),牌...
作為A股半導(dǎo)體設(shè)備龍頭,北方華創(chuàng)一舉一動(dòng)都備受產(chǎn)業(yè)關(guān)注。今年1月初,北方華創(chuàng)公布公告稱,公司擬定增募資21億元,定增的認(rèn)購對(duì)象包括國家大基金、公司實(shí)控人北京電控、京國瑞基金和北京集成電路基金等,認(rèn)購額分別為9.2億元、6億元、5億元、8000萬元。其中,大基金及北京電控合計(jì)認(rèn)購額已經(jīng)超過了七成。不過,該定增方案已發(fā)生變化。7月6日,北方華創(chuàng)發(fā)...
近年來,我們身邊的智能手機(jī)、車室內(nèi)操作、公共設(shè)施的預(yù)訂和售票機(jī)等設(shè)備,已普遍采用觸摸輸入的方式。在這樣的形勢下,可折疊(注1)智能手機(jī)在去年亮相并引發(fā)關(guān)注,作為將平板電腦與智能手機(jī)融合在一起的一個(gè)新附加值門類,各廠家都在陸續(xù)開發(fā)新產(chǎn)品。另一方面,傳統(tǒng)型智能手機(jī)的技術(shù)開發(fā)也在向穿孔(注2)和無槽口(注3)等全屏化方向發(fā)展,預(yù)計(jì)今...
車規(guī)級(jí)功率半導(dǎo)體模塊(IGBT模塊),是新能源汽車電控系統(tǒng)上的核心零部件之一,由于直接控制全車交直流轉(zhuǎn)換、高低壓功率調(diào)控等核心指標(biāo),被稱為新能源汽車的“最強(qiáng)大腦”。 新能源汽車產(chǎn)業(yè)正進(jìn)入加速發(fā)展的新階段。長期以來,關(guān)鍵動(dòng)力總成資源是制約中國汽車工業(yè)發(fā)展的重要因素,突破這一瓶頸,對(duì)提升國內(nèi)新能源汽車的核心競爭力將起到重要促進(jìn)作用。特別...

史海拾趣

小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved