RT-Thread學習記錄3 簡單的線程實例—跑馬燈實驗

以下爲看視頻筆記。。。。

1 線程狀態轉換圖

線程初始狀態是還沒有運行, 當調用rt_thread_startup()後線程就是就緒態,系統根據就緒態的優先級來確定那個線程運行,

運行態執行完後就返回到就緒態。

當運行態需要共享資源時,調用圖中1的函數後變爲掛起態(也稱阻塞態)。

運行態調用rt_thread_exit()後變爲關閉態。

系統運行就在圖中的狀態之間轉換,主要在就緒狀態,運行狀態,掛起狀態三者之間轉換。

當線程不需要運行時,可以調用rt_thread_exit()處於關閉態。

 

每一個操作系統中都存在一個“系統心跳”時鐘,是操作系統中最小的時鐘單位。這個時鐘負.責系統和時間相關的- -些操作。作爲操作系統運行的時間尺度,心跳時鐘是由硬件定時器的定時中斷產生。

系統的心跳時鐘我們也常稱之爲系統滴答或時鐘節拍,系統滴答的頻率需要我們根據cpu的處理能力來決定。

時鐘節拍使得內核可以將線程延時若干個整數時鐘節拍,以及線程等待事件發生時,提供等待超時的依據。

頻率越快,內核函數介入系統運行的機率就越大,內核佔用的處理器時間就越長,系統的負荷就變大;

頻率越小,時間處理精度又不夠;

我們在stm32平臺上一般設置系統滴答頻率爲100HZ,即每個滴答的時間是10ms

在代碼board.c裏有STM32硬件定時器配置函數如下圖,配置時鐘爲1 秒時間跳100次 = 100 Hz,一個時鐘節拍爲10毫秒。

在程序中使用延時函數rt_thread_mdelay(num),延時num毫秒。就是又系統嘀嗒延時來完成的

3 跑馬燈的創建

 IO口的操作

3.1 IO初始化
void rt_pin_mode(rt_base_t pin,rt_base_t mode)
mode 可爲:
  PIN_MODE_OUTPUT          
  PIN_MODE_INPUT           
  PIN_MODE_INPUT_PULLUP    
  PIN_MODE_INPUT_PULLDOWN  
  PIN_MODE_OUTPUT_OD  
選擇引腳,在文件Drive的drv_gpio.c中有,如MCU引腳爲144個,選
   #if (STM32F10X_PIN_NUMBERS == 144)下的對應名字
    __STM32_PIN(1, E, 2),//括號裏第一個參數代表上面函數rt_pin_mode()第一個參數pin.
    __STM32_PIN(2, E, 3),//引腳PE3 ,代表 pin = 2
    __STM32_PIN(3, E, 4),//引腳PE4 ,代表 pin = 3
    __STM32_PIN(4, E, 5),
    __STM32_PIN(5, E, 6),

 
3.2 IO寫入
void rt_pin_write(rt_base_t pin,rt_base_t value)
value可爲:
  PIN_HAIGH
  PIN_LOW
3.3 IO 讀取
 int rt_pin_read(rt_base_t pin)

創建跑馬燈線程,我創建動態線程,運行。

int thread_led_test(void)
{
    /* 創建線程1,名稱是led,入口是led_entry*/
    tid1 = rt_thread_create("led",                    //線程名字
                            led_entry,                //線程入口函數
                            RT_NULL,     
                            512,
                            10, 10);
    
    /* 如果獲得線程控制塊,啓動這個線程 */
    if (tid1 != RT_NULL)          //判斷線程是否創建成功
        rt_thread_startup(led);   //成功創建,則從初始態變爲就緒態
 
    return 0;
}
/* 線程led的入口函數,完成LED的閃爍操作 */
static void led_entry(void *parameter)
{
    rt_uint32_t count = 0;
    rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);  //設置LED_PIN引腳的模式,要包含頭文件 
                                            //#include <rtdevice.h>


    while (1)
    {
        rt_pin_write(LED_PIN, PIN_HIGH);
        rt_kprintf("led on, count : %d\r\n", count);
        rt_thread_delay(500);               //延時500 ms執行時,其他的線程在運行
        rt_pin_write(LED_PIN, PIN_LOW);
        rt_kprintf("led off\r\n");               
        rt_thread_delay(500);
        //rt_thread_delay()以時鐘節拍爲單位延時,
        //rt_thread_mdelay()以1毫秒節拍爲單位延時,
        //rt_thread_sleep()以時鐘節拍爲單位延時。三個函數都起到延時的作用
    }
}
在main函數裏調用thread_led_test()就可以了。

先將線程棧的大小設置一個固定值(如2048),在線程運行時通過查看線程棧的使用情況,根據情況設置合理的棧大小。

一般將線程棧最大使用量設置爲70%。

通過命令 list_thread 打印所有線程的信息。圖中 tshell 爲命令行所在的線程,tidle爲空閒線程,

pri 爲線程的優先級 ,status爲線程的狀態,sp 爲線程的sp指針。

stack size  創建線程時線程棧的大小分配,max used 已經使用線程棧的百分比,left tick 剩餘時鐘滴答。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章