精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

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

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

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

Openwrt開發(fā)指南 第19章 驅(qū)動開發(fā)之LED驅(qū)動程序

嵌入式大雜燴 ? 來源:嵌入式大雜燴 ? 作者:嵌入式大雜燴 ? 2023-07-03 09:01 ? 次閱讀

開發(fā)環(huán)境:

主機(jī):Ubuntu12.04

開發(fā)板:RT5350

Openwrt:Openwrt15.05

1 硬件原理

1688309450899wor3360rqz

圖1

由于發(fā)光二級管單向?qū)щ娞匦裕粗挥性谡螂妷海?a target="_blank">二極管的正極接正,負(fù)極接負(fù))下才能導(dǎo)通發(fā)光。如圖所示,如果 GPIO 輸出高電平,LED 就會被點(diǎn)亮,如果 GPIO 輸出低電平,LED 就會熄滅。對于我們的驅(qū)動開發(fā),無論是單片機(jī)、還是 ARM、或者是我們的 MIPS,核心思想,都是讀寫某個地址,即操作某個寄存器

2 寄存器介紹

RT5350 一共有 28 個 GPIO 管腳,這 28 個 GPIO,除了 GPIO0,其他全部是與其他功能引腳復(fù)用的。

表1

1688309451600teuqhsf0kc

GPIO1、GPIO2 與 I2C 復(fù)用。

表2

1688309451852hx8f10ostq

GPIO3~6 與 SPI 復(fù)用。

表3

1688309452118oauupjmw22

GPIO7~14,與 UARTF 即串口 2 復(fù)用。

這些復(fù)用關(guān)系,都可以通過查閱 RT5350 的芯片手冊得到。

而這些復(fù)用功能, 我們可以通過 GPIOMODE 寄存器來進(jìn)行選擇, 通過查手冊得知,GPIOMODE寄存器的地址為 0x10000060。

表4

1688309452394a7cho2pt83

GPIOMODE 寄存器 bit0 位用于選擇 GPIO1、GPIO2 對應(yīng)的引腳是用于 IIC 總線,還是用于GPIO。

GPIOMODE 寄存器 bit1 位用于選擇 GPIO3~6 對應(yīng)的引腳用于 SPI 總線,還是用于 GPIO。

GPIOMODE 寄存器 bit2~4 位用于選擇 UARTF 對應(yīng)的引腳工作于哪個模塊,具體定義如下。

表5

16883094530699yqb8mgmpb

從該表格可以看出,UARTF 對應(yīng)的引腳,可以工作于 UARTF、PCM、I2S、GPIO 四種模式,將 GPIOMODE 寄存器 bit24 位設(shè)置為相應(yīng)的值,就能讓這些引腳工作于相應(yīng)的模式,比如將GPIOMODE 寄存器 bit24 位的值設(shè)置為 7,則讓相應(yīng)的引腳工于 GPIO 模式。

當(dāng)將相應(yīng)的引腳設(shè)置為 GPIO 以后,我們接下來就需要操作該 GPIO 了,操作 GPIO 不外乎就是設(shè)置 GPIO 是輸入還是輸出、讓其輸出高電平還是低電平、讀取其電平狀態(tài)。不管是哪種操作,都有對應(yīng)的寄存器。

表6

1688309453462jtao5bg1g4

GPIO21_00_DIR 寄存器,用于設(shè)置 GPIO0~21 的方向,當(dāng)相應(yīng)的位被設(shè)置為 1,則表示相應(yīng)的 GPIO 管腳被設(shè)置為了輸出,如果被設(shè)置為了 0,則相應(yīng)的 GPIO 引腳就被設(shè)置為了輸入。

表7

1688309453878j8wuc87w5l

當(dāng)相應(yīng) GPIO 引腳被設(shè)置為輸出時,設(shè)置 GPIO21_00_DATA 寄存器的相應(yīng)位為 1,則讓該GPIO 引腳輸出了高電平,如果設(shè)置 GPIO21_00_DATA 寄存器的相應(yīng)位為 0,則讓該 GPIO 引腳輸出了低電平。

當(dāng)相應(yīng) GPIO 引腳被設(shè)置為輸入時,則通過讀取 GPIO21_00_DATA 寄存器時,就能讀取相應(yīng)的 GPIO 引腳的狀態(tài)。

關(guān)于更多的 GPIO 操作的寄存器介紹,請自行查閱手冊。

3 編寫驅(qū)動程序

我們通過前面章節(jié)的學(xué)習(xí),掌握了驅(qū)動程序的框架,接下來我們就來寫一個驅(qū)動程序,實現(xiàn)操作 GPIO25、GPIO26 兩個 GPIO 引腳。具體驅(qū)動實現(xiàn)如下。

#include < linux/mm.h >
#include < linux/miscdevice.h >
#include < linux/slab.h >
#include < linux/vmalloc.h >
#include < linux/mman.h >
#include < linux/random.h >
#include < linux/init.h >
#include < linux/raw.h >
#include < linux/tty.h >
#include < linux/capability.h >
#include < linux/ptrace.h >
#include < linux/device.h >
#include < linux/highmem.h >
#include < linux/crash_dump.h >
#include < linux/backing-dev.h >
#include < linux/bootmem.h >
#include < linux/splice.h >
#include < linux/pfn.h >
#include < linux/export.h >
#include < linux/io.h >
#include < linux/aio.h >
#include < linux/kernel.h >
#include < linux/module.h >
#include < asm/uaccess.h >
#define MYLEDS_LED1_ON 0
#define MYLEDS_LED1_OFF 1
#define MYLEDS_LED2_ON 2
#define MYLEDS_LED2_OFF 3

volatile unsigned long *GPIOMODE;
volatile unsigned long *GPIO27_22_DIR;
volatile unsigned long *GPIO27_22_DATA;
static struct class *myleds_class;

static int myleds_open(struct inode *inode, struct file *file)
{
/* 讓 GPIO#25、GPIO#26 輸出高電平,同時熄滅 LED1、LED2 */
*GPIO27_22_DATA &= ~((1< 3)|(1< 4));
return 0;
}
static long myleds_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case MYLEDS_LED1_ON:// 點(diǎn)亮 LED1
*GPIO27_22_DATA |= (1< 3);
break;
case MYLEDS_LED1_OFF: // 熄滅 LED1
*GPIO27_22_DATA &= ~(1< 3);
break;
case MYLEDS_LED2_ON:// 點(diǎn)亮 LED2
*GPIO27_22_DATA |= (1< 4);
break;
case MYLEDS_LED2_OFF: // 熄滅 LED2
*GPIO27_22_DATA &= ~(1< 4);
break;
default:
break;
}
return 0;
}
/* 1.分配、設(shè)置一個 file_operations 結(jié)構(gòu)體 */
static struct file_operations myleds_fops = {
.owner = THIS_MODULE, /* 這是一個宏,推向編譯
模塊時自動創(chuàng)建的__this_module 變量 */
.open = myleds_open,
.unlocked_ioctl = myleds_unlocked_ioctl,
};
int major;
static int __init myleds_init(void)
{
/* 2.注冊 */
major = register_chrdev(0, "myleds", &myleds_fops);
/* 3.自動創(chuàng)建設(shè)備節(jié)點(diǎn) */
/* 創(chuàng)建類 */
myleds_class = class_create(THIS_MODULE, "myleds");
/* 類下面創(chuàng)建設(shè)備節(jié)點(diǎn) */
device_create(myleds_class, NULL, MKDEV(major, 0), NULL, "myleds"); //
/dev/myleds
/* 4.硬件相關(guān)的操作 */
/* 映射寄存器的地址 */
GPIOMODE = (volatile unsigned long *)ioremap(0x10000060, 4);
GPIO27_22_DIR = (volatile unsigned long *)ioremap(0x10000674, 4);
GPIO27_22_DATA = (volatile unsigned long *)ioremap(0x10000670, 4);
/* 設(shè)置相應(yīng)管腳用于 GPIO */
/*
** LED1 ---- GPIO#25
** LED2 ---- GPIO#26
*/
*GPIOMODE |= (0x1< 14);
/* 將 GPIO#25、GPIO#26 設(shè)置為輸出 */
*GPIO27_22_DIR = (1< 3)|(1< 4);
return 0;
}
static void __exit myleds_exit(void)
{
unregister_chrdev(major, "myleds");
device_destroy(myleds_class, MKDEV(major, 0));
class_destroy(myleds_class);
iounmap(GPIOMODE);
iounmap(GPIO27_22_DIR);
iounmap(GPIO27_22_DATA);
}
module_init(myleds_init);
module_exit(myleds_exit);
MODULE_LICENSE("GPL");

因為我們的開發(fā)板上跑的是 Linux 系統(tǒng),因此操作某個寄存器的時候,需要將它的物理地址映射成虛擬地址,通過 ioremap()函數(shù)來進(jìn)行映射,該函數(shù)的參數(shù) 1,就是對應(yīng)的寄存器的物理地址,參數(shù) 2 是需要映射多大,可以理解為寄存器有多大,返回值就是該寄存器對應(yīng)的虛擬地址了。

當(dāng)寄存器地址映射為虛擬地址以后,然后基于前面寫的驅(qū)動程序框架,就能很容易的編寫出自己的 GPIO 驅(qū)動了,和操作單片機(jī)沒有什么差別了。

4 編寫 Makefile

驅(qū)動寫好以后,自然是需要想辦法來編譯該驅(qū)動了,通過前面的章節(jié)的學(xué)習(xí),我們需要給該驅(qū)動編寫一個 Makefile 文件。

首先是新建一個文件夾,取名為 myleds,然后在 myleds 目錄下再新建一個文件夾,取名為 src,然后將上面的驅(qū)動文件復(fù)制到 src 目錄下,并且在 src 目錄下新建一個 Makefile,

內(nèi)容如下。

obj-m += myleds.o

然后回到 myleds 目錄,再創(chuàng)建一個 Makefile 文件,內(nèi)容如下。

# 
#Copyright (C) 2008-2019 OpenWrt.org
#
#This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=myleds
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define KernelPackage/myleds
SUBMENU:=Other modules
# DEPENDS:=@!LINUX_3_3
TITLE:=Motor driver
FILES:=$(PKG_BUILD_DIR)/myleds.ko
# AUTOLOAD:=$(call AutoLoad,30,myleds,1)
KCONFIG:=
endef
define KernelPackage/myleds/description
This is a myleds drivers
endef
MAKE_OPTS:= \\
ARCH="$(LINUX_KARCH)" \\
CROSS_COMPILE="$(TARGET_CROSS)" \\
SUBDIRS="$(PKG_BUILD_DIR)"
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \\
$(MAKE_OPTS) \\
modules
endef
$(eval $(call KernelPackage,myleds))

如果不清楚為什么這樣編寫 Makefile 文件,請查看前面章節(jié)的相關(guān)介紹。

5 編譯驅(qū)動程序

接下來,我們就來配置編譯驅(qū)動程序。首先將 myleds 文件夾傳到 OpenWrt 源碼的package/kernel 目錄下。然后進(jìn)入 OpenWrt 源碼的頂層目錄,執(zhí)行 make menuconfig。

$ make menuconfig

在彈出的菜單界面里,首先進(jìn)入 Kernel modules 選項。

Kernel modules  --- >
Other modules  --- >
< * > kmod-myleds

16883094542989qo0m5w9t8

圖2

然后我們就能看到我們的驅(qū)動程序的選項了 kmod-myleds,將它配置成M,也可以便已進(jìn)入內(nèi)核。最后,退出保存。然后再執(zhí)行編譯命令。

make V=99

編譯完成以后,就能在源碼目錄下的bin/ramips/packages/base目錄下看到我們的內(nèi)核模塊驅(qū)動程序的軟件包 kmod-myleds_3.18.109-1_ramips_24kec.ipk。

19.6 動態(tài)的加載和卸載內(nèi)核驅(qū)動模塊軟件包

通過前面的努力,我們終于得到了我們自己的內(nèi)核驅(qū)動模塊軟件包了。接下來就來使用它。首先將 kmod-myleds_3.18.109-1_ramips_24kec.ipk 軟件包傳到開發(fā)板上面。然后使用 opkg install 命令來安裝軟件包。

opkg install kmod-myleds_3.18.109-1_ramips_24kec.ipk

1688309454667y59me39sp3

使用 opkg list 命令來查看已經(jīng)安裝了哪些軟件包。這里是否執(zhí)行該命令都無所謂。接下來進(jìn)入我們的/lib/modules/3.18.109目錄,就能看到我們的驅(qū)動程序模塊了。

cd lib/modules/3.18.109/

1688309454875gdnscpsfh4

接下來就通過 insmod 命令來裝載驅(qū)動模塊。

insmod myleds.ko

驅(qū)動安裝成功以后,我們就能看到 GPIO 驅(qū)動對應(yīng)的設(shè)備節(jié)點(diǎn)了。

168830945511587ihzpsapz

審核編輯:湯梓紅

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

    關(guān)注

    242

    文章

    23153

    瀏覽量

    658609
  • 驅(qū)動程序
    +關(guān)注

    關(guān)注

    19

    文章

    827

    瀏覽量

    47969
  • 開發(fā)板
    +關(guān)注

    關(guān)注

    25

    文章

    4959

    瀏覽量

    97214
  • 開發(fā)環(huán)境
    +關(guān)注

    關(guān)注

    1

    文章

    222

    瀏覽量

    16586
  • OpenWrt
    +關(guān)注

    關(guān)注

    10

    文章

    128

    瀏覽量

    39268
收藏 人收藏

    評論

    相關(guān)推薦

    Openwrt開發(fā)指南 16 驅(qū)動開發(fā)字符設(shè)備驅(qū)動程序框架

    我們在學(xué)習(xí) C 語言的時候,知道每個應(yīng)用程序的入口函數(shù),即第一個被執(zhí)行的函數(shù)是 main函數(shù),那么,我們自己的驅(qū)動程序,哪個函數(shù)是入口函數(shù)呢?
    的頭像 發(fā)表于 06-30 09:01 ?3366次閱讀
    <b class='flag-5'>Openwrt</b><b class='flag-5'>開發(fā)指南</b> <b class='flag-5'>第</b>16<b class='flag-5'>章</b> <b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b><b class='flag-5'>之</b>字符設(shè)備<b class='flag-5'>驅(qū)動程序</b>框架

    Openwrt開發(fā)指南 25 配置OpenWrt支持網(wǎng)絡(luò)攝像頭

    Openwrt開發(fā)指南 25 配置OpenWrt支持網(wǎng)絡(luò)攝像頭
    的頭像 發(fā)表于 07-13 08:56 ?2326次閱讀
    <b class='flag-5'>Openwrt</b><b class='flag-5'>開發(fā)指南</b> <b class='flag-5'>第</b>25<b class='flag-5'>章</b> 配置<b class='flag-5'>OpenWrt</b>支持網(wǎng)絡(luò)攝像頭

    PCI驅(qū)動程序開發(fā)實例

    本文采用微軟的驅(qū)動程序開發(fā)包Device Driver Kit(DDK)開發(fā)出來的PCI驅(qū)動程序通用性好,兼容性強(qiáng)。本文給出了基于DSP的PCI驅(qū)動
    發(fā)表于 12-30 11:10 ?6777次閱讀
    PCI<b class='flag-5'>驅(qū)動程序</b><b class='flag-5'>開發(fā)</b>實例

    Openwrt開發(fā)指南 15 驅(qū)動開發(fā)字符設(shè)備驅(qū)動程序概念介紹

    從上到下,一個軟件系統(tǒng)可以分為:應(yīng)用程序、庫、操作系統(tǒng)(內(nèi)核)、驅(qū)動程序開發(fā)人員可以專注于自己熟悉的部分,對于相鄰層,只需要了解它的接口,無需關(guān)注它的實現(xiàn)細(xì)節(jié)。
    的頭像 發(fā)表于 06-30 09:00 ?2693次閱讀
    <b class='flag-5'>Openwrt</b><b class='flag-5'>開發(fā)指南</b> <b class='flag-5'>第</b>15<b class='flag-5'>章</b> <b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b><b class='flag-5'>之</b>字符設(shè)備<b class='flag-5'>驅(qū)動程序</b><b class='flag-5'>之</b>概念介紹

    Openwrt開發(fā)指南 17 驅(qū)動開發(fā)字符設(shè)備驅(qū)動程序

    首先將 RT5350_drv 文件夾傳到 OpenWrt 源碼的chaos_calmer/package/kernel 目錄下。然后進(jìn)入 OpenWrt 源碼的頂層目錄,執(zhí)行 make menuconfig。
    的頭像 發(fā)表于 07-02 09:20 ?3140次閱讀
    <b class='flag-5'>Openwrt</b><b class='flag-5'>開發(fā)指南</b> <b class='flag-5'>第</b>17<b class='flag-5'>章</b> <b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b><b class='flag-5'>之</b>字符設(shè)備<b class='flag-5'>驅(qū)動程序</b>

    Openwrt開發(fā)指南 18 驅(qū)動開發(fā)字符設(shè)備應(yīng)用程序

    在前面的章節(jié)中, 我們成功的寫出了我們自己的驅(qū)動程序, 并且向應(yīng)用程序提供了 open、read、write 三個接口,那么接下來我們就來編寫應(yīng)用程序,調(diào)用這些接口。
    的頭像 發(fā)表于 07-02 09:21 ?2511次閱讀
    <b class='flag-5'>Openwrt</b><b class='flag-5'>開發(fā)指南</b> <b class='flag-5'>第</b>18<b class='flag-5'>章</b> <b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b><b class='flag-5'>之</b>字符設(shè)備應(yīng)用<b class='flag-5'>程序</b>

    Openwrt開發(fā)指南 20 驅(qū)動開發(fā)LED應(yīng)用程序

    在前面的章節(jié)中, 我們成功的寫出了我們自己的驅(qū)動程序, 并且向應(yīng)用程序提供了 open、ioctl 兩個接口,那么接下來我們就來編寫應(yīng)用程序,調(diào)用這些接口。
    的頭像 發(fā)表于 07-03 09:02 ?2596次閱讀
    <b class='flag-5'>Openwrt</b><b class='flag-5'>開發(fā)指南</b> <b class='flag-5'>第</b>20<b class='flag-5'>章</b> <b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b><b class='flag-5'>之</b><b class='flag-5'>LED</b>應(yīng)用<b class='flag-5'>程序</b>

    Openwrt開發(fā)指南 22 Openwrt串口的使用2

    在上一中,我們成功的讓驅(qū)動程序支持了串口 2,并且做了簡單的測試。接下來,我們就為串口 2 添加一個應(yīng)用程序,從而實現(xiàn) Wi-Fi 串口。實現(xiàn)過程非常簡單,首先進(jìn)入 OpenWrt
    的頭像 發(fā)表于 07-05 09:09 ?3984次閱讀
    <b class='flag-5'>Openwrt</b><b class='flag-5'>開發(fā)指南</b> <b class='flag-5'>第</b>22<b class='flag-5'>章</b> <b class='flag-5'>Openwrt</b>串口的使用2

    Openwrt開發(fā)指南 24 配置開發(fā)板支持U盤

    Openwrt開發(fā)指南 24 配置開發(fā)板支持U盤
    的頭像 發(fā)表于 07-13 08:55 ?3027次閱讀
    <b class='flag-5'>Openwrt</b><b class='flag-5'>開發(fā)指南</b> <b class='flag-5'>第</b>24<b class='flag-5'>章</b> 配置<b class='flag-5'>開發(fā)</b>板支持U盤

    CE驅(qū)動程序開發(fā)指南資料分享

    CE驅(qū)動程序開發(fā)指南資料分享
    發(fā)表于 08-03 12:03

    測試系統(tǒng)開發(fā)指南:理解驅(qū)動程序和直接輸入輸出

    測試系統(tǒng)開發(fā)指南:理解驅(qū)動程序和直接輸入/輸出
    發(fā)表于 08-21 14:53

    WINCE驅(qū)動程序開發(fā)指南

    CE驅(qū)動程序所有驅(qū)動皆為動態(tài)鏈接庫驅(qū)動實現(xiàn)中可以調(diào)用所有標(biāo)準(zhǔn)的APICE驅(qū)動程序模型本機(jī)驅(qū)動程序流接口驅(qū)
    發(fā)表于 07-07 15:06 ?41次下載

    SN3340 LED驅(qū)動IC應(yīng)用開發(fā)指南

    SN3340 LED驅(qū)動IC應(yīng)用開發(fā)指南:The SN3340 is a continuous mode inductive step-downconverter, designed
    發(fā)表于 01-07 17:20 ?31次下載

    Windows WDM設(shè)備驅(qū)動程序開發(fā)指南

    書主要介紹Windows 98和Windows 2000新的驅(qū)動程序模型(WDM)。描述了WDM設(shè)備驅(qū)動程序的結(jié)構(gòu)、功能和開發(fā)方法.
    發(fā)表于 12-12 15:31 ?0次下載
    Windows WDM設(shè)備<b class='flag-5'>驅(qū)動程序</b><b class='flag-5'>開發(fā)指南</b>

    UM2298_STM32Cube BSP驅(qū)動程序開發(fā)指南

    UM2298_STM32Cube BSP驅(qū)動程序開發(fā)指南
    發(fā)表于 11-22 19:19 ?1次下載
    UM2298_STM32Cube BSP<b class='flag-5'>驅(qū)動程序</b><b class='flag-5'>開發(fā)指南</b>