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 剩余时钟滴答。

 

 

 

 

 

 

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