RT-Thread 17. 中断发送信号量后线程去处理信号量

1. 代码

//sem.c

#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"

#define THREAD_PRIORITY 25
#define THREAD_TIMESLICE 5

#define LED3_PIN GET_PIN(B, 3)
ALIGN(RT_ALIGN_SIZE)
static char thread3_stack[1024];
static struct rt_thread thread3;
static struct rt_semaphore keyPress1_sem;
void KeyScanCallBack(void)
{
  rt_sem_release(&keyPress1_sem); 
}
static void rt_thread3_entry(void *parameter)
{
  static rt_err_t result;
//  static int cnt = 0;
  while(1)
  {
    /* 永 久 方 式 等 待 信 号 量, 获 取 到 信 号 量, 则 执 行 number 自 加 的 操 作 */
    result = rt_sem_take(&keyPress1_sem, RT_WAITING_FOREVER);
    if (result != RT_EOK)
    {
      rt_kprintf("t3 take a static semaphore, failed.\n");
      return;
    }
    else
    {
      rt_kprintf("t3 take a static semaphore");
      rt_pin_write(LED3_PIN, PIN_HIGH);
      rt_thread_mdelay(1000);
      rt_pin_write(LED3_PIN, PIN_LOW);
//      if(++cnt >= 5)
//      {
//        rt_sem_detach(&keyPress1_sem);
//        return;
//      }
    }
  }
}

void Key1PressTaskInit(void)
{
  /* 初 始 化 3 个 信 号 量 */
  rt_sem_init(&keyPress1_sem, "keyPress1_sem", 0, RT_IPC_FLAG_FIFO);
  rt_pin_mode(LED3_PIN, PIN_MODE_OUTPUT);
  rt_thread_init(&thread3,
                "thread3",
                rt_thread3_entry,
                RT_NULL,
                &thread3_stack[0],
                sizeof(thread3_stack),
                THREAD_PRIORITY-1, THREAD_TIMESLICE);  
  rt_thread_startup(&thread3);  
}

//usrtimer.c

#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"


/* 定时器的控制块 */
static struct rt_timer timer3;
static int cnt = 0;

#define KEY1_PIN GET_PIN(C, 5)

static uint8_t keyVal = 0;

void KeyScanCallBack(void);
static void keyscan(void* parameter)
{
  static uint8_t i = 0;
  uint8_t val;
  
  val = rt_pin_read(KEY1_PIN);
  if(val == 0)
  {
    if(i < 200)
    {
      i ++;
    }
  }
  else
  {
    if(i >= 2)
    {
      keyVal = 1;
      rt_kprintf("key press val is %d\n",keyVal);
      KeyScanCallBack();
      keyVal = 0;
    }
    i = 0;
  }
}

void keyscan_init(void)
{
    rt_pin_mode(KEY1_PIN, PIN_MODE_INPUT);
    rt_timer_init(&timer3, 
                    "timerKeyscan",   /* 定时器名字是 timer2 */
                    keyscan, /* 超时时回调的处理函数 */
                    RT_NULL, /* 超时函数的入口参数 */
                    5, /* 定时长度为 5 个 OS Tick */
                    RT_TIMER_FLAG_PERIODIC); /* 单次定时器 */  

    rt_timer_start(&timer3);
}

//main.c

#include <rthw.h>
#include <stdio.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"
#include "gd32f3x0.h"

/* defined the LED2 pin: PC6 */
#define LED1_PIN GET_PIN(B, 1)
#define LED2_PIN GET_PIN(B, 2)


#define delay_ms(x)   rt_thread_mdelay(x)

#define RT_USR1_THREAD_PRIO        6
#define USR1_THREAD_NAME          "usr1"
static struct rt_thread usr1_thread;
static rt_uint8_t usr1_thread_stack[500];


void rt_thread_usr1_entry(void *parameter)
{
    /* set LED2 pin mode to output */
    rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT);
    while (1)
    {
        rt_pin_write(LED2_PIN, PIN_HIGH);
        rt_thread_mdelay(2000);
        rt_pin_write(LED2_PIN, PIN_LOW);
        rt_thread_mdelay(3000);
    } 
}

void keyscan_init(void);
void Key1PressTaskInit(void);

int main(void)
{
  
  keyscan_init();
  Key1PressTaskInit();

  rt_thread_init(&usr1_thread,
               USR1_THREAD_NAME,
               rt_thread_usr1_entry,
               RT_NULL,
               &usr1_thread_stack[0],
               sizeof(usr1_thread_stack),
               RT_USR1_THREAD_PRIO,
               20);
  rt_thread_startup(&usr1_thread);

  /* set LED1 pin mode to output */
  rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);

  while (1)
  {
      rt_pin_write(LED1_PIN, PIN_HIGH);
      rt_thread_mdelay(500);
      rt_pin_write(LED1_PIN, PIN_LOW);
      rt_thread_mdelay(600);
  }
}
2.测试

按键一次,rt_sem_release(&keyPress1_sem);执行一次信号量值value加1。按键可以很快,但rt_thread3_entry()执行以下需要1s多。

rt_kprintf("t3 take a static semaphore");
rt_pin_write(LED3_PIN, PIN_HIGH);
rt_thread_mdelay(1000);
rt_pin_write(LED3_PIN, PIN_LOW);

即生产过快,消耗过慢。
在这里插入图片描述

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值