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.
");
      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
",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);

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