RT-Thread操作系统学习(3)

消息队列,遵从先进先出的原则,我们利用正点原子的水星开发板STM32F767IG为实验开发板,进行RT-Thread操作系统的消息队列实验。

static rt_thread_t receive_thread=RT_NULL;
static rt_thread_t send_thread=RT_NULL;

static rt_mq_t test_mq=RT_NULL;
static void receive_thread_entry(void* parameter);
static void send_thread_entry(void* parameter);

int main(void)
{
    rt_pin_mode(KEY0_PIN,PIN_MODE_INPUT);
    rt_pin_mode(KEY1_PIN,PIN_MODE_INPUT);
    test_mq = rt_mq_create("test_mq",4,20,RT_IPC_FLAG_FIFO);
    if(test_mq!=RT_NULL)
    {
        rt_kprintf("megass success\r\n");
    }
    receive_thread = rt_thread_create("receive",receive_thread_entry,RT_NULL,512,17,20);
    if(receive_thread!=RT_NULL)
    {
        rt_thread_startup(receive_thread);
    }
    send_thread=rt_thread_create("send",send_thread_entry,RT_NULL,512,18,20);
    if(send_thread!=RT_NULL)
    {
        rt_thread_startup(send_thread);
    }
}

static void receive_thread_entry(void* parameter)
{
    rt_err_t uwRet=RT_EOK;
    uint32_t r_queue;
    while (1)
    {
        uwRet=rt_mq_recv(test_mq,&r_queue,sizeof(r_queue),RT_WAITING_FOREVER);
        if(uwRet==RT_EOK)
        {
            rt_kprintf("receive:%d\r\n",r_queue);
        }
        else
        {
            rt_kprintf("receive fail\r\n");
        }
    }
    
}

static void send_thread_entry(void* parameter)
{
    rt_err_t uwRet=RT_EOK;
    uint32_t send_data1=1;
    uint32_t send_data2=2;
    while (1)
    {
        if (rt_pin_read(KEY0_PIN))
        {
            while (rt_pin_read(KEY0_PIN))
            {
                /* code */
            }
            rt_kprintf("key0 press\r\n");
            uwRet =rt_mq_send(test_mq,&send_data1,sizeof(send_data1));
            if(uwRet!=RT_EOK)
            {
                rt_kprintf("fail\r\n");
            }
            /* code */
        }
        if(rt_pin_read(KEY1_PIN))
        {
            while (rt_pin_read(KEY1_PIN))
            {
                /* code */
            }
            rt_kprintf("key1 press\r\n");
            uwRet =rt_mq_send(test_mq,&send_data2,sizeof(send_data2));
            if(uwRet!=RT_EOK)
            {
                rt_kprintf("fail\r\n");
            }
        }
				rt_thread_delay(10);
    }
    
}

对于这两个线程我们可以使接受的线程的优先级大于发送函数的优先级,就会出现每按一下按键就会接收到对应的信息。

然后再修改发送和接受函数的优先级,使得发送的优先级大于发送的优先级。就会出现在两个按键全部按下就会出现俩条消息全部接收。

信号量是一种用于解决线程间同步问题的内核对象,线程可以获取和释放它,从而达到同步和互斥的目的。信号量就像一把钥匙,把一段临界去锁住,只允许有钥匙的线程进行访问,线程拿到了钥匙,才允许他进入临界区,而离开后把钥匙传递给排队在后面的等待线程,让后续线程依次进入临界区,当然这会出现一个小小的问题,就是一个优先级低的线程一直拿着这把钥匙,就是不给你优先级高的线程,让你干等着,我优先级低的一直在这里得瑟,就是不给你,对于创造这个操作系统的工程师怎么可能会允许你一直在这里得瑟,我要制裁你这种行为,当然这已经属于互斥量的问题领域了,我们还是先讲信号量,信号量被人分为二值信号量和计数信号量,我们这里只讲二值信号量,因为他们两个几乎相同,只讲一个就可以了。

static rt_thread_t receive_thread=RT_NULL;
static rt_thread_t send_thread=RT_NULL;
static rt_sem_t test_sem =RT_NULL;
static void receive_thread_entry(void* parameter);
static void send_thread_entry(void* parameter);
int main(void)
{
    test_sem=rt_sem_create("test_sem",1,RT_IPC_FLAG_FIFO);
    if(test_sem!=RT_NULL)
    {
        rt_kprintf("sem success\r\n");
    }
    receive_thread =rt_thread_create("receive",receive_thread_entry,RT_NULL,512,2,20);
    if(receive_thread!=RT_NULL)
    {
        rt_thread_startup(receive_thread);
        rt_kprintf("receive success\r\n");
    }
    send_thread=rt_thread_create("send",send_thread_entry,RT_NULL,512,3,20);
    if(send_thread!=RT_NULL)
    {
        rt_thread_startup(send_thread);
        rt_kprintf("send success\r\n");
    }
}
static void receive_thread_entry(void* parameter)
{
    while (1)
    {
        rt_sem_take(test_sem,RT_WAITING_FOREVER);
        if(ucValue[0]==ucValue[1])
        {
            rt_kprintf("successful\r\n");
        }
        rt_sem_release(test_sem);
        rt_thread_delay(1000);
    }
    
}
static void send_thread_entry(void* parameter)
{
    while (1)
    {
        rt_sem_take(test_sem,RT_WAITING_FOREVER);
        ucValue[0]++;
        rt_thread_delay(100);
        ucValue[1]++;
        rt_sem_release(test_sem);
        rt_thread_yield();
    }
    
}

 这样我们就可以看见串口一直打印successful。

学习完信号量我们就开始学习互斥量,估计大家看完我上面写的信号量,怕都不使用信号量了,其实只要用的得当,就不会出现这样的问题,要不然互斥量干脆干掉信号量算了,信号量之所以有,肯定有好处的。其实互斥量也属于信号量,是一种相互排斥的信号量,是一种特殊的二值信号量,他和信号量不同的是,他支持互斥量的所有权,递归访问以及优先级翻转的特性。

当然在这里我给大家分享一个学习清华北大课程的好网站,可以让你直接不花钱就学习清华北大的优秀课程。

lib-pku · GitHublib-pku has 2 repositories available. Follow their code on GitHub.https://github.com/lib-pku

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GD32开发者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值