Zephyr程序初探(5):thread程序

来源:互联网 发布:大学生网购数据 编辑:程序博客网 时间:2024/06/05 11:29

这次的程序使用了中断、thread、semaphore,按键被按下后GPIO的中断callback被执行,发送semaphore使检测按键的thread得以执行,然后判断长按或者短按发送相应semaphore让相应的thread执行,除输出信息外LED会根据短按或者长按来闪烁1或者2次。

#include <zephyr.h>#include <board.h>#include <device.h>#include <gpio.h>#include <misc/util.h>#include <misc/printk.h>/* define LED and Button pin */#define LED_PORT    LED0_GPIO_PORT#define LED_PIN     LED0_GPIO_PIN#define LED_FLASH_TIME  100//ms#define BTN_PORT    SW0_GPIO_NAME#define BTN_PIN     SW0_GPIO_PIN/* define semaphore */K_SEM_DEFINE(semPress, 0, 1);K_SEM_DEFINE(semHold, 0, 1);K_SEM_DEFINE(semBtnIntr, 0, 1);/* define global device */struct device *gDevLed;struct device *gDevBtn;static struct gpio_callback gpio_cb;/* define thread parameter */#define STACKSIZE   1024#define PRIORITY_EVENT  7#define PRIORITY_INTR   6void ledOnOff(uint32_t on){    gpio_pin_write(gDevLed, LED_PIN, !on);}void ledFlash(uint32_t times){    while(times) {        ledOnOff(1);        k_sleep(LED_FLASH_TIME);        ledOnOff(0);        if(--times)            k_sleep(LED_FLASH_TIME);    }}uint32_t isKeyDown(void){    uint32_t val;    gpio_pin_read(gDevBtn, BTN_PIN, &val);    return !val;}void threadPress(void *dummy1, void *dummy2, void *dummy3){    ARG_UNUSED(dummy1);    ARG_UNUSED(dummy2);    ARG_UNUSED(dummy3);    while(1) {        k_sem_take(&semPress, K_FOREVER);        printk("btn pressed\n");        ledFlash(1);    }}void threadHold(void *dummy1, void *dummy2, void *dummy3){    ARG_UNUSED(dummy1);    ARG_UNUSED(dummy2);    ARG_UNUSED(dummy3);    while(1) {        k_sem_take(&semHold, K_FOREVER);        printk("btn hold\n");        ledFlash(2);    }}void threadBtnIntr(void *dummy1, void *dummy2, void *dummy3){    ARG_UNUSED(dummy1);    ARG_UNUSED(dummy2);    ARG_UNUSED(dummy3);    uint32_t count;    bool bHold;    while(1) {        k_sem_take(&semBtnIntr, K_FOREVER);        count = 0;        bHold = false;        do {            k_sleep(50);            count++;            if(count > 6) {                bHold = true;                break;            }        }while(isKeyDown());        if(bHold)            k_sem_give(&semHold);        else            k_sem_give(&semPress);    }}K_THREAD_DEFINE(threadPress_id, STACKSIZE, threadPress, NULL, NULL, NULL,         PRIORITY_EVENT, 0, K_NO_WAIT);K_THREAD_DEFINE(threadHold_id, STACKSIZE, threadHold, NULL, NULL, NULL,         PRIORITY_EVENT, 0, K_NO_WAIT);K_THREAD_DEFINE(threadBtnIntr_id, STACKSIZE, threadBtnIntr, NULL, NULL, NULL,         PRIORITY_INTR, 0, K_NO_WAIT);void btnIntrCb(struct device *gpio, struct gpio_callback *cb, uint32_t pin){    k_sem_give(&semBtnIntr);}void helloMsg(void){    printk("\n************************************************\n");    printk("**\n");    printk("** Welcome to visit http://blog.csdn.net/veabol\n");    printk("** Thread program start!\n");    printk("**\n");    printk("************************************************\n");}void main (void){    helloMsg();    printk("configure led\n");    gDevLed = device_get_binding(LED_PORT);    if (!gDevLed) {        printk("error\n");        return;    }    gpio_pin_configure(gDevLed, LED_PIN, GPIO_DIR_OUT);    ledOnOff(0);    printk("configure button\n");    gDevBtn = device_get_binding(BTN_PORT);    if (!gDevBtn) {        printk("error\n");        return;    }    gpio_pin_configure(gDevBtn, BTN_PIN,         GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | GPIO_INT_ACTIVE_LOW | GPIO_PUD_PULL_UP);    gpio_init_callback(&gpio_cb, btnIntrCb, BIT(BTN_PIN));    gpio_add_callback(gDevBtn, &gpio_cb);    gpio_pin_enable_callback(gDevBtn, BTN_PIN);}

通过系统函数K_SEM_DEFINE定义三个信号量semPress,semHold,semBtnIntrK_THREAD_DEFINE初始化三个thread,分别用于等待按键中断和短按和长按的事件,threadBtnIntr()等待semBtnIntr即按键中断的发生,threadPress()是短按的线程等待semPress被发送,threadHold()是长按的线程等待semHold被发送。
main()函数初始化LED和按键,注册并使能按键的callback函数btnIntrCb(),当中断发生时btnIntrCb()被调用,并且发送信号使threadBtnIntr()得以继续执行,根据按键持续的时间长短分别发送短按和长按的信号 ,相应的线程也得以执行,测试时对按键进行短按和长按能够看到LED闪烁1次或者2次,通过串口能够看到如何信息:

**************************************************** Welcome to visit http://blog.csdn.net/veabol** Thread program start!**************************************************configure ledconfigure buttonbtn pressedbtn pressedbtn holdbtn hold