0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【i.MX6ULL】驅(qū)動(dòng)開發(fā)10—阻塞&非阻塞式按鍵檢測(cè)

碼農(nóng)愛學(xué)習(xí) ? 來源:碼農(nóng)愛學(xué)習(xí) ? 作者:碼農(nóng)愛學(xué)習(xí) ? 2022-05-27 09:08 ? 次閱讀

上篇文章:介紹了linux中的五種I/O模型,本篇,就來使用阻塞式I/O非用阻塞式I/O兩種方式進(jìn)行按鍵的讀取實(shí)驗(yàn),并對(duì)比之前使用輸入捕獲和中斷法檢測(cè)的按鍵程序,查看CPU的使用率是否降低。

1 阻塞I/O方式的按鍵檢測(cè)

1.1 阻塞I/O之等待隊(duì)列

阻塞訪問最大的好處就是當(dāng)設(shè)備文件不可操作的時(shí)候進(jìn)程可以進(jìn)入休眠態(tài),這樣可以將CPU資源讓出來。但是,當(dāng)設(shè)備文件可以操作的時(shí)候就必須喚醒進(jìn)程,一般在中斷函數(shù)里面完成喚醒工作。Linux 內(nèi)核提供了等待隊(duì)列(wait queue)來實(shí)現(xiàn)阻塞進(jìn)程的喚醒工作。

等待隊(duì)列頭使用結(jié)構(gòu)體wait_queue_head_t 表示:

struct __wait_queue_head { 
	spinlock_t       lock; 
	struct list_head task_list; 
}; 

typedef struct __wait_queue_head wait_queue_head_t; 

使用 init_waitqueue_head 函數(shù)初始化等待隊(duì)列頭:

/**
 * q: 要初始化的等待隊(duì)列頭
 * return: 無
 */
void init_waitqueue_head(wait_queue_head_t *q) 

當(dāng)設(shè)備不可用的時(shí), 將這些進(jìn)程對(duì)應(yīng)的等待隊(duì)列項(xiàng)(wait_queue_t )添加到等待隊(duì)列里面:

struct __wait_queue { 
	unsigned int      flags; 
    void              *private; 
    wait_queue_func_t func; 
    struct list_head  task_list;
}; 

typedef struct __wait_queue wait_queue_t;

使用宏 DECLARE_WAITQUEUE 定義并初始化一個(gè)等待隊(duì)列項(xiàng):

DECLARE_WAITQUEUE(name, tsk)

當(dāng)設(shè)備不可訪問的時(shí)候就需要將進(jìn)程對(duì)應(yīng)的等待隊(duì)列項(xiàng)添加到前面創(chuàng)建的等待隊(duì)列頭中:

/**
 * q: 要加入的等待隊(duì)列頭
 * wait:要加入的等待隊(duì)列項(xiàng)
 * return: 無
 */
void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) 

當(dāng)設(shè)備可以訪問以后再將進(jìn)程對(duì)應(yīng)的等待隊(duì)列項(xiàng)從等待隊(duì)列頭中刪除即可:

/**
 * q: 要?jiǎng)h除的等待隊(duì)列頭
 * wait:要?jiǎng)h除的等待隊(duì)列項(xiàng)
 * return: 無
 */
void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) 

當(dāng)設(shè)備可以使用的時(shí)候就要喚醒進(jìn)入休眠態(tài)的進(jìn)程:

void wake_up(wait_queue_head_t *q) 
void wake_up_interruptible(wait_queue_head_t *q) 

1.2 阻塞I/O程序編寫

這里僅介紹與之前按鍵程序的主要區(qū)別。

1.2.1驅(qū)動(dòng)程序

阻塞讀取邏輯如下,首先要定義一個(gè)等待隊(duì)列,當(dāng)按鍵沒有按下時(shí),就要阻塞等待了(將等待隊(duì)列添加到等待隊(duì)列頭),然后進(jìn)行行一次任務(wù)切換,交出CPU的使用權(quán)。等待有按鍵按下時(shí),會(huì)有信號(hào)喚醒該等待,并將按鍵值返回給應(yīng)用層的程序。

static ssize_t imx6uirq_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{
    int ret = 0;
    unsigned char keyvalue = 0;
    unsigned char releasekey = 0;
    struct imx6uirq_dev *dev = (struct imx6uirq_dev *)filp->private_data;
    
    /* 定義一個(gè)等待隊(duì)列 <-------------------------- */
    DECLARE_WAITQUEUE(wait, current);
    
    /* 沒有按鍵按下 <------------------------------ */
    if(atomic_read(&dev->releasekey) == 0)
    {
        /* 將等待隊(duì)列添加到等待隊(duì)列頭 <------------ */
        add_wait_queue(&dev->r_wait, &wait);
        
        /* 設(shè)置任務(wù)狀態(tài) <-------------------------- */
        __set_current_state(TASK_INTERRUPTIBLE);
        
        /* 進(jìn)行一次任務(wù)切換 <---------------------- */
        schedule();
        
        /* 判斷是否為信號(hào)引起的喚醒 <-------------- */
        if(signal_pending(current))
        {
            ret = -ERESTARTSYS;
            goto wait_error;
        }
        
        /* 將當(dāng)前任務(wù)設(shè)置為運(yùn)行狀態(tài) <-------------- */
        __set_current_state(TASK_RUNNING);
        
        /* 將對(duì)應(yīng)的隊(duì)列項(xiàng)從等待隊(duì)列頭刪除 <-------- */
        remove_wait_queue(&dev->r_wait, &wait);
    }

    keyvalue = atomic_read(&dev->keyvalue);
    releasekey = atomic_read(&dev->releasekey);

    /* 有按鍵按下 */
    if (releasekey)
    {
        //printk("releasekey!\r\n");
        if (keyvalue & 0x80)
        {
            keyvalue &= ~0x80;
            ret = copy_to_user(buf, &keyvalue, sizeof(keyvalue));
        }
        else
        {
            goto data_error;
        }
        atomic_set(&dev->releasekey, 0); /* 按下標(biāo)志清零 */
    }
    else
    {
        goto data_error;
    }
    return 0;

wait_error:
    set_current_state(TASK_RUNNING);           /* 設(shè)置任務(wù)為運(yùn)行態(tài) */
    remove_wait_queue(&dev->r_wait, &wait);    /* 將等待隊(duì)列移除 */
    return ret;
    
data_error:
    return -EINVAL;
}

按鍵的定時(shí)器去抖邏輯中的,讀取到按鍵后,觸發(fā)喚醒,這里以其中的一個(gè)按鍵為例,其邏輯如下:

void timer1_function(unsigned long arg)
{
    unsigned char value;
    struct irq_keydesc *keydesc;
    struct imx6uirq_dev *dev = (struct imx6uirq_dev *)arg;

    keydesc = &dev->irqkeydesc[0];

    value = gpio_get_value(keydesc->gpio); /* 讀取IO值 */
    if(value == 1) /* 按下按鍵 */
    {
        printk("get key1: high\r\n");
        atomic_set(&dev->keyvalue, keydesc->value);
    }
    else /* 按鍵松開 */
    {
        printk("key1 release\r\n");
        atomic_set(&dev->keyvalue, 0x80 | keydesc->value);
        atomic_set(&dev->releasekey, 1); /* 標(biāo)記松開按鍵,即完成一次完整的按鍵過程 */            
    }
    
    /* 喚醒進(jìn)程 */
    if(atomic_read(&dev->releasekey))
    {
        wake_up_interruptible(&dev->r_wait);
    }
}

1.2.2 應(yīng)用程序

應(yīng)用程序不需要修改,還使用之前的輪詢讀取的方式,為了在測(cè)試時(shí)看出阻塞與非阻塞方式的區(qū)別,在read函數(shù)前后添加打印,如果程序運(yùn)行正常,會(huì)先打印read前一句的打印,直到有按鍵按下后,read函數(shù)才被接觸阻塞,read后一句的打印才會(huì)打印出。

/* 循環(huán)讀取按鍵值數(shù)據(jù)! */
while(1)
{
    printf("[APP] read begin...\r\n");
    read(fd, &keyvalue, sizeof(keyvalue));
    printf("[APP] read end\r\n");
    if (keyvalue == KEY1VALUE)
    {
        printf("[APP] KEY1 Press, value = %#X\r\n", keyvalue);
    }
    else if (keyvalue == KEY2VALUE)
    {
        printf("[APP] KEY2 Press, value = %#X\r\n", keyvalue);
    }
}

1.2 實(shí)驗(yàn)

和之前一樣,使用Makefile編譯驅(qū)動(dòng)程序和應(yīng)用程序,并復(fù)制到nfs根文件系統(tǒng)中。

開始測(cè)試,按如下圖,當(dāng)沒有按鍵按下時(shí),應(yīng)用程序被阻塞:

pYYBAGKPlZmAX1imAADhTzUjZGc198.png

按鍵程序在后臺(tái)運(yùn)行,此時(shí)使用top指令開查看CPU的使用率,可以發(fā)現(xiàn)阻塞式按鍵驅(qū)動(dòng)這種方式,CPU的暫用率幾乎為0,雖然按鍵應(yīng)用程序中仍實(shí)現(xiàn)循環(huán)讀取的方式,但因平時(shí)讀取不到按鍵值,按鍵應(yīng)用程序被阻塞住了,CPU的使用權(quán)被讓出,自然CPU的使用率就降下來了。

poYBAGKPlaGAGg-HAADTTCGipSQ073.png

2 非阻塞I/O方式的按鍵檢測(cè)

按鍵應(yīng)用程序以非阻塞的方式讀取,按鍵驅(qū)動(dòng)程序也要以非阻塞的方式立即返回。應(yīng)用程序可以通過select、poll或epoll函數(shù)來 查詢?cè)O(shè)備是否可以操作,驅(qū)動(dòng)程序使用poll函數(shù)。

2.1 非阻塞I/O之select/poll

select函數(shù)原型:

/**
 * nfs: 所要監(jiān)視的這三類文件描述集合中,最大文件描述符加1
 * readfds: 用于監(jiān)視指定描述符集的讀變化
 * writefds: 用于監(jiān)視文件是否可以進(jìn)行寫操作
 * exceptfds: 用于監(jiān)視文件的異常
 * timeout: 超時(shí)時(shí)間
 * return: 0 超時(shí)發(fā)生, -1 發(fā)生錯(cuò)誤, 其他值 可以進(jìn)行操作的文件描述符個(gè)數(shù) 
 */
int select(int    nfds,  
           fd_set *readfds,  
           fd_set *writefds, 
           fd_set *exceptfds,  
           struct timeval *timeout) 

其中超時(shí)時(shí)間使用結(jié)構(gòu)體timeval表示:

struct timeval { 
   long tv_sec;  /* 秒   */ 
   long tv_usec; /* 微妙 */  
}; 

當(dāng)timeout為NULL的時(shí)候就表示無限等待。

poll函數(shù)原型:

/**
 * fds: 要監(jiān)視的文件描述符集合以及要監(jiān)視的事件,為一個(gè)數(shù)組
 * nfds: 監(jiān)視的文件描述符數(shù)量
 * timeout: 超時(shí)時(shí)間,單位為 ms
 * return: 0 超時(shí)發(fā)生, -1 發(fā)生錯(cuò)誤, 其他值 可以進(jìn)行操作的文件描述符個(gè)數(shù) 
 */
int poll(struct pollfd *fds,  
         nfds_t nfds,  
         nt     timeout) 

2.2 非阻塞I/O程序編寫

2.2.1 驅(qū)動(dòng)程序

poll函數(shù)處理部分:

unsigned int imx6uirq_poll(struct file *filp, struct poll_table_struct *wait)
{
    unsigned int mask = 0;
    struct imx6uirq_dev *dev = (struct imx6uirq_dev *)filp->private_data;

    /* 將等待隊(duì)列頭添加到poll_table中 */
    poll_wait(filp, &dev->r_wait, wait);
    
    /* 按鍵按下 */
    if(atomic_read(&dev->releasekey))
    {
        mask = POLLIN | POLLRDNORM;            /* 返回PLLIN */
    }
    return mask;
}

/* 設(shè)備操作函數(shù) */
static struct file_operations imx6uirq_fops = {
    .owner = THIS_MODULE,
    .open = imx6uirq_open,
    .read = imx6uirq_read,
    .poll = imx6uirq_poll,
};

read函數(shù)處理部分:

static ssize_t imx6uirq_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{
    int ret = 0;
    unsigned char keyvalue = 0;
    unsigned char releasekey = 0;
    struct imx6uirq_dev *dev = (struct imx6uirq_dev *)filp->private_data;

    /* 非阻塞訪問 */
    if (filp->f_flags & O_NONBLOCK)
    {
        /* 沒有按鍵按下,返回-EAGAIN */
        if(atomic_read(&dev->releasekey) == 0)
        {
            return -EAGAIN;
        }
    }
    /* 阻塞訪問 */
    else
    {
        /* 加入等待隊(duì)列,等待被喚醒,也就是有按鍵按下 */
        ret = wait_event_interruptible(dev->r_wait, atomic_read(&dev->releasekey)); 
        if (ret)
        {
            goto wait_error;
        }
    }

    keyvalue = atomic_read(&dev->keyvalue);
    releasekey = atomic_read(&dev->releasekey);

    /* 有按鍵按下 */
    if (releasekey)
    {
        //printk("releasekey!\r\n");
        if (keyvalue & 0x80)
        {
            keyvalue &= ~0x80;
            ret = copy_to_user(buf, &keyvalue, sizeof(keyvalue));
        }
        else
        {
            goto data_error;
        }
        atomic_set(&dev->releasekey, 0); /* 按下標(biāo)志清零 */
    }
    else
    {
        goto data_error;
    }
    return 0;

wait_error:
    return ret;
data_error:
    return -EINVAL;
}

2.2.2 應(yīng)用程序

2.2.2.1 poll方式讀取

注意open函數(shù)的參數(shù)是O_NONBLOCK,即非阻塞訪問,并且為了在測(cè)試時(shí)看出阻塞讀取與非阻塞讀取的區(qū)別,在poll函數(shù)前后添加打印,如果程序正常運(yùn)行,poll函數(shù)則不會(huì)被阻塞,500ms超時(shí)未讀取到按鍵值后會(huì)再次循環(huán)讀取,實(shí)際效果就是可以看打一直有打印輸出。

    filename = argv[1];
    fd = open(filename, O_RDWR | O_NONBLOCK);    /* 非阻塞訪問 */
    if (fd < 0)
    {
        printf("[APP] Can't open file %s\r\n", filename);
        return -1;
    }

    /* 構(gòu)造結(jié)構(gòu)體 */
    fds.fd = fd;
    fds.events = POLLIN;
    while(1)
    {
        printf("[APP] poll begin... \r\n", data);
        ret = poll(&fds, 1, 500);
        printf("[APP] poll end \r\n", data);
        /* 數(shù)據(jù)有效 */
        if (ret > 0)
        {
            ret = read(fd, &data, sizeof(data));
            if(ret < 0)
            {
                /* 讀取錯(cuò)誤 */
            }
            else
            {
                if(data)
                {
                    printf("[APP] key value = %d \r\n", data);
                }
            }     
        }
        /* 超時(shí) */
        else if (ret == 0)
        {
            /* 用戶自定義超時(shí)處理 */
        }
        /* 錯(cuò)誤 */
        else
        {
            /* 用戶自定義錯(cuò)誤處理 */
        }
    }

2.2.2.2 select方式讀取

select方式讀取與poll方式類似,都是非阻塞讀取,程序類似:

while(1)
{
    FD_ZERO(&readfds);
    FD_SET(fd, &readfds);
    /* 構(gòu)造超時(shí)時(shí)間 */
    timeout.tv_sec = 0;
    timeout.tv_usec = 500000; /* 500ms */
    ret = select(fd + 1, &readfds, NULL, NULL, &timeout);
    switch (ret)
    {
            /* 超時(shí) */
        case 0:
            /* 用戶自定義超時(shí)處理 */
            break;
            /* 錯(cuò)誤 */
        case -1:
            /* 用戶自定義錯(cuò)誤處理 */
            break;
            /* 可以讀取數(shù)據(jù) */
        default:
            if(FD_ISSET(fd, &readfds))
            {
                ret = read(fd, &data, sizeof(data));
                if (ret < 0)
                {
                    /* 讀取錯(cuò)誤 */
                }
                else
                {
                    if (data)
                    {
                        printf("key value=%d\r\n", data);
                    }
                }
            }
            break;
    }
}

2.3 實(shí)驗(yàn)

2.3.1 poll方式讀取

和之前一樣,使用Makefile編譯驅(qū)動(dòng)程序和應(yīng)用程序,并復(fù)制到nfs根文件系統(tǒng)中。

開始測(cè)試,按如下圖,當(dāng)沒有按鍵按下時(shí),應(yīng)用程序也沒有被阻塞,從不斷的打印就可以看出應(yīng)用程序在循環(huán)運(yùn)行。當(dāng)有按鍵按下時(shí),能夠讀取到對(duì)應(yīng)的按鍵值。

poYBAGKPla2AK2AvAAFXYivs3Nw253.png

按鍵程序在后臺(tái)運(yùn)行,此時(shí)使用top指令開查看CPU的使用率,可以發(fā)現(xiàn)非阻塞式按鍵驅(qū)動(dòng)這種方式,CPU的暫用率也幾乎為0,雖然按鍵應(yīng)用程序中仍實(shí)現(xiàn)循環(huán)讀取的方式,但poll函數(shù)有500ms的超時(shí)設(shè)置,在超時(shí)等待的時(shí)間里,CPU的使用權(quán)也是被讓出,所以CPU的使用率也降下來了。

pYYBAGKPlbaAI8KoAADgwZ96jiI026.png

2.3.2 select方式讀取

select方式讀取與poll方式讀取的效果一樣。

使用ps指令查看poll方式的按鍵進(jìn)行號(hào),使用kill殺帶該進(jìn)程,再運(yùn)行select方式的按鍵應(yīng)用程序:

pYYBAGKPlb2APMsmAAFCfrAxqzU216.png

select非阻塞讀取的方式,CPU的暫用率也幾乎為0:

poYBAGKPlcOATnPFAADSWuc1oCw810.png

3 總結(jié)

本篇使用兩種I/O模型進(jìn)行按鍵讀取:阻塞式I/O非用阻塞式I/O,通過實(shí)際的實(shí)驗(yàn),對(duì)比兩者方式的實(shí)際運(yùn)行效果與主要區(qū)別,并查看CPU的占用率,兩種方式的CPU使用率都幾乎為0。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5046

    文章

    18817

    瀏覽量

    298563
  • 驅(qū)動(dòng)
    +關(guān)注

    關(guān)注

    12

    文章

    1790

    瀏覽量

    84910
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207912
  • i.MX6
    +關(guān)注

    關(guān)注

    1

    文章

    37

    瀏覽量

    16251
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    i.MX6ULL 驅(qū)動(dòng)開發(fā)7—按鍵輸入捕獲與GPIO輸入配置與高低電平讀取

    本篇主要介紹了i.MX6ULL按鍵檢測(cè)的使用,主要的知識(shí)點(diǎn)是設(shè)備樹的修改,以及GPIO的輸入配置與高低電平的讀取。
    的頭像 發(fā)表于 05-24 09:11 ?5940次閱讀
    <b class='flag-5'>i.MX6ULL</b> <b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>7—<b class='flag-5'>按鍵</b>輸入捕獲與GPIO輸入配置與高低電平讀取

    i.MX6ULL嵌入Linux開發(fā)1-uboot移植初探

    本系列教程以i.MX6ULL處理器的ARM開發(fā)板為實(shí)驗(yàn)基礎(chǔ),學(xué)習(xí)記錄嵌入Linux開發(fā)的各種知識(shí)與經(jīng)驗(yàn),主要內(nèi)容包括嵌入Linux移植,
    的頭像 發(fā)表于 03-07 08:57 ?3738次閱讀
    <b class='flag-5'>i.MX6ULL</b>嵌入<b class='flag-5'>式</b>Linux<b class='flag-5'>開發(fā)</b>1-uboot移植初探

    使用i.MX6ULL開發(fā)板進(jìn)行Linux根文件系統(tǒng)的完善

    上一篇推文講了怎么移植根文件系統(tǒng),并在i.MX6ULL開發(fā)板中運(yùn)行起來,但是會(huì)出現(xiàn)一些提示,現(xiàn)在來進(jìn)行根文件的完善。
    發(fā)表于 10-17 11:13 ?706次閱讀

    移植NXP官方linux 5.4內(nèi)核到i.MX6ULL開發(fā)

    本文描述移植NXP官方 linux 5.4 內(nèi)核到i.MX6ULL開發(fā)板。
    發(fā)表于 12-19 11:10 ?1896次閱讀

    i.MX6UL/i.MX6ULL開發(fā)常見問題】單獨(dú)編譯內(nèi)核,uboot生成很多文件,具體用哪一個(gè)?

    i.MX6UL/i.MX6ULL開發(fā)常見問題》基于米爾電子 i.MX6UL/i.MX6ULL產(chǎn)品(V.
    發(fā)表于 07-01 17:50

    I.MX6ULL終結(jié)者開發(fā)板裸機(jī)仿真jlink調(diào)試

    I.MX6ULL‘終結(jié)者’開發(fā)板預(yù)留了JTAG仿真接口,并給出了開發(fā)文檔,可以實(shí)現(xiàn)在JLINK仿真器條件下的單步跟蹤、斷點(diǎn)調(diào)試等功能,使得開發(fā)研究i
    發(fā)表于 07-07 10:56

    i.MX6ULL開發(fā)板硬件資源

    迅為i.MX6ULL 終結(jié)者開發(fā)板硬件資源非常豐富,幾乎將 i.MX6ULL 芯片的所有資源都擴(kuò)展引出到底板上了,底板提供了豐富的外設(shè)接口,開發(fā)板的尺寸是 190mm*125mm,充分
    發(fā)表于 12-29 06:18

    i.MX6ULL核心板資源

    操作系統(tǒng)鏡像&amp;amp;燒寫工具提供資料提供相關(guān)的 BSP 源代碼、文件系統(tǒng)源代碼其它默認(rèn)配置i.MX6ULL、512MB DDR3、4GB EMMC可選配置i.MX6ULL、2
    發(fā)表于 07-12 17:50

    初識(shí) i.MX6ULL 寄存器

    裸機(jī)開發(fā)_L1_匯編LED實(shí)驗(yàn)0. 本節(jié)目標(biāo)1. 硬件層電路2. 初識(shí) i.MX6ULL 寄存器2.1 i.MX6ULL 時(shí)鐘控制寄存器2.2 i.MX6ULL IO復(fù)用寄存器2.3
    發(fā)表于 12-20 07:13

    《Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解》第8章、Linux設(shè)備驅(qū)動(dòng)中的阻塞阻塞IO

    《Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解》第8章、Linux設(shè)備驅(qū)動(dòng)中的阻塞阻塞IO
    發(fā)表于 10-27 11:35 ?9次下載
    《Linux設(shè)備<b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>詳解》第8章、Linux設(shè)備<b class='flag-5'>驅(qū)動(dòng)</b>中的<b class='flag-5'>阻塞</b>與<b class='flag-5'>非</b><b class='flag-5'>阻塞</b>IO

    飛凌i.MX6ULL開發(fā)板的評(píng)測(cè),再次進(jìn)階擁有更高的性價(jià)比

    處理器MCIMX6Y2開發(fā)設(shè)計(jì),采用先進(jìn)的ARMCortex-A7內(nèi)核,運(yùn)行速度高達(dá)800MHz。i.MX6ULL應(yīng)用處理器包括一個(gè)集成的電源管理模塊,降低了外接電源的復(fù)雜性,并簡(jiǎn)化了上電時(shí)序。
    發(fā)表于 10-27 11:55 ?1381次閱讀
    飛凌<b class='flag-5'>i.MX6ULL</b><b class='flag-5'>開發(fā)</b>板的評(píng)測(cè),再次進(jìn)階擁有更高的性價(jià)比

    基于NXP i.MX6ULL處理器的FETMX6ULL-C核心板

    合作伙伴,飛凌不負(fù)美譽(yù),基于i.MX6ULL匠心打造的FETMX6ULL-S核心板一經(jīng)問世便好評(píng)不斷,且已有數(shù)百家來自工業(yè)、醫(yī)療、電力、物聯(lián)網(wǎng)等行業(yè)的用戶采用此款核心板快速完成了整機(jī)產(chǎn)品的開發(fā)上市。
    發(fā)表于 04-11 15:05 ?1058次閱讀
    基于NXP <b class='flag-5'>i.MX6ULL</b>處理器的FETMX<b class='flag-5'>6ULL</b>-C核心板

    i.MX6ULL驅(qū)動(dòng)開發(fā)4——點(diǎn)亮LED(寄存器版)

    本篇主要介紹了如何通過操作寄存器來點(diǎn)亮i.MX6ULL開發(fā)板上的led,通過編寫LED對(duì)應(yīng)的驅(qū)動(dòng)程序和應(yīng)用程序,實(shí)現(xiàn)程序設(shè)計(jì)的分層。
    的頭像 發(fā)表于 05-21 21:26 ?2841次閱讀
    【<b class='flag-5'>i.MX6ULL</b>】<b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>4——點(diǎn)亮LED(寄存器版)

    【北京迅為】i.MX6ULL開發(fā)板移植 Debian 文件系統(tǒng)

    【北京迅為】i.MX6ULL開發(fā)板移植 Debian 文件系統(tǒng)
    的頭像 發(fā)表于 02-10 15:34 ?1011次閱讀
    【北京迅為】<b class='flag-5'>i.MX6ULL</b><b class='flag-5'>開發(fā)</b>板移植 Debian 文件系統(tǒng)

    基于i.MX6ULL的掉電檢測(cè)設(shè)計(jì)與軟件測(cè)試

    基于i.MX6ULL的掉電檢測(cè)設(shè)計(jì)與軟件測(cè)試基于i.MX6ULL平臺(tái)設(shè)計(jì)實(shí)現(xiàn)掉電檢測(cè)功能,首先選擇一路IO,利用IO電平變化觸發(fā)中斷,在編寫驅(qū)動(dòng)
    的頭像 發(fā)表于 11-09 10:40 ?686次閱讀
    基于<b class='flag-5'>i.MX6ULL</b>的掉電<b class='flag-5'>檢測(cè)</b>設(shè)計(jì)與軟件測(cè)試