如何分别为beaglebone安装kerenl与PC安装Wt

beaglebone开发流程初体验-永远的LED_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
beaglebone开发流程初体验-永远的LED
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢为BeagleBone-Black安装LinuxEZSDK和CCS提要 - CSDN博客
为BeagleBone-Black安装LinuxEZSDK和CCS提要
在TI官网上下载
网址:/tool/linuxezsdk-sitara,选择BeagleBone-Black对应的AM335X系列进行下载,也就是在以下的网址http://software-/sitara_linux/esd/AM335xSDK/latest/index_FDS.html下载
ti-sdk-am335x-evm-06.00.00.00-Linux-x86-Install.bin
和CCS V5.3
下载完成后,将这两个文件放到/home/&用户名&/目录底下
如果是32bit的linux系统,直接进行下面的1 和 2步,如果是64bit的linux系统,请先安装ia32-libs。
1》打开terminal,输入tar xvzf命令对解压时要和放在同一路径
然后运行,根据提示将CCS和Linux SDK 安装好。
安装好后再进行setup.sh和source envirnomet-setup.sh.
接下来的可以看,写得非常详细。
注意在CCS安装过程中,请按默认选项安装,因为里面有个交叉编译选项是ARM9的,我们用的是A8,所以按默认装就行了。
详情请看http://processors./index.php/Sitara_Linux_Software_Developer%E2%80%99s_Guide
http://processors./index.php/Code_Composer_Studio_v5_Users_Guide
本文已收录于以下专栏:
相关文章推荐
根据之前的博客, 我们已经可以从tftp下载内核 并且挂载nfs为根文件系统了, 我们可以到 /tftp 目录下查看到启动系统使用的内核和设备数文件:
zImage-am335x-evm.bin
StarterWare为何物,简单说是像STM32库函数一样的东西。
StarterWare for AM335X 最新下载地址:
http://software-/dsps/ds...
apt-get install libncurses5-dev
接着说第二个方面,安装cross-toolchain,注意,我前面说过,我不会说使用SDK来安装,我从头讲自己怎么建立一个cross-toolchain。以下都基于此。
一、cross-toolcha...
BeagleBone Black(BBB) 是一种基于ARM Cortex A8处理器的低成本开发平台。此开发板是基于发行版制作的。由一支希望统一嵌入式系统发行版的小型团队开发,他们希望操作系统是稳定...
二、如何使用debian
  不习惯angstrom,一直用debian,决定装一个debian。参照 BeagleBone
Black Debian安装这个帖子(http://www.eeboar...
Beaglebone Black开发板安装驱动Beaglebone Black开发板安装驱动Beaglebone Black开发板安装驱动...
1) 下载Debian镜像文件
http://rcn-ee.net/deb/flasher/wh
... 0-.img.xz
2) 下载7zip解压缩工具,解压出img镜像文件...
BBB板第三课:Debian7.5系统安装和远程控制BBB板
因为BBB板系统是Debian 7.4,据说使用Debian系统可以实现很多BBB板的无缝连接,可以更好的学习和控制...
他的最新文章
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)帮助中心联系我们关于85开发
热门搜索:
全部技术分类
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=20 limit 100
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=26 limit 100
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=30 limit 100
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=24 limit 100
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=25 limit 100
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=27 limit 100
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=28 limit 100
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=31 limit 100
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=33 limit 100
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=34 limit 100
标准方案SQL Error: select cat_id,cat_name,parent_id from 85kf_fangan.ecs_category where parent_id=32 limit 100
您当前的位置:&>&&>&&&&BeagleBone机器人开发指南-4.3下载和安装OpenCV
  4.3下载和安装OpenCV——一个全功能的视觉库  已经连接好摄像头,接下来可以使用开源社区提供的功能强大的软件了。对于计算机视觉来说,著名的就是OpenCV。  4.3.1任务准备  现在需要安装OpenCV。OpenCV是一个完整的视觉库,提供捕获、处理和保存图像的能力。在正式开始之前,需要为SD卡扩展分区,从而可以下载需要的应用软件。将Linux操作系统写入SD卡后,你只复制了 2 GB的镜像。所以SD卡会被认为只有2 GB容量,但这并不是SD卡的实际大小,因此需要重新进行分区。  为此,需要使用一些命令。首先,打开终端窗口。我使用的SD卡容量是8 GB,如果你的SD卡容量不同,可能看到不同的数字。不过庆幸的是,操作过程中只需要使用默认数值即可,所以实际上不需要了解与SD卡有关的情况。输入命令sudosu,然后输人你的密码。按照以下步骤操作:输人11/dev/mmcblk *,输出如下图所示:现在幵始对腿clbkO设备进行修改,输入fdisk/dev/mmclbk0命令输入P,可以看到当前的分区情况,如下图所示:  4.需要扩展第二个分区设备,即/dev/mmcblkOp2。首先删除此分区,然后创建一个新的分区。在此过程中,SD卡上原有的信息还将保留着。输入d,然后输入2,即分区2。再次输人p,可以看到:5.使用默认的数值创建新的分区,占用SD卡剩余的所有空间。在命令提示符处输入n,再输人p,然后输人2,每个命令输完后都要单击回车键。第二个分区再次出现,只不过根据不同大小的SD卡容量,显示的大小也会不同。  6.注意到第二个分区比之前的要大。输人w命令写入修改。然后重启系统,输入命令reboot。7.后一步是扩展文件系统。在系统重启后,输入sudo SU,然后输人口令。现在输入df命令,检查磁盘剩余空间。可以看到:8.需要扩容的是/dev/mmcblkOp2 分区。输入 resize2fs/dev/mmcblk0p3命令,然后输人df命令。可以看到:  现在SD卡就可以使用了。  4.3.2任务执行首先,需要下载OpenCV和一系列库文件。有许多可能的步骤,这里给出在我的系统上的操作方式。系统启动后,打开终端窗口,按顺序输入以下命令:  1. sudoapt-get install update:如果很久没有执行过该命令,建议昏先执行该命令。这将下载许多更新的软件包,所以好确保系统处于新状态。  2. sudo apt-get install build-essential:前面章节应该已经操作过,如果没有操作过,现在需要执行该命令。  3. sudo apt-get install libavformat-dev:该库文件提供对音频流和视频流的编解码操作。  4. sudoapt~get install ffmpeg:该库文件提供对音频流和视频流的转码操作。  5. sudoapt-get install libcv2 .3 libcvaux2 .3 libhighgui2 .3 : S些是OpenCV的基本库。注意软件包包含的版本号。随着OpenCV的发展,会出现新的版本。如果找不到2. 3版本,那么就尝试2. 4版本,或者在Google上查询OpenCV的新版本号。  6. sudo apt-get install python-opencv: OpenCV 的 Python 开发包,如果使用Python语言开发会需要。  7. sudoapt-get install opencv-doc: OpenCV 的文档〇  8. sudoapt-get install libcv-dev:提供了编译 OpenCV 所需的头文件和静态库文件。  9. sudoapt-get install libcvaux-dev:提供了编译 OpenCV 所需的开发工具。  10. sudoapt-get install libhighgui-dev:提供了编译 OpenCV 所需的头文件和静态库文件。  11. 确保当則位于home目录下,然后输人cp-r/usr/share/doc/opencv_doc/examples./:将所有的例子复制到home目录。  12. fej人命令cd./examples/c,进人到examples/c目录,然后输人shbuild_all.sh,开始编译 OpenCV。  现在已经做好了使用OpenCV库的准备,在完成一些简单的任务时,我喜欢使用Python语言,所以我会展示Python的例子。如果喜欢使用C语言,也可以去尝试。为了使用Python例子,需要更多的库。因为openCV在处理图像时需要进行矩阵处理,所以输人 sudo apt-get install python-numpy 命令。  一切就绪,可以开始使用Python的例子。进入到Python目录,输人命令cd/home/Ubuntu/examples/python。在该目录下,你会发现大量有用的样例代码并可以运行。不过,这需要在BeagleBcme Black上连接显示器,或者使用er连接。打开一个终端窗口,输人Python camera .py,可以看到:  我的camera窗口是黑色,没有显示出摄像头输出的图像。需要改变摄像头和OpenCV支持的图像分辨率。为此,编辑camera .py文件,增加两行代码,如下图所示:  这两句代码将捕获图像的分辨率改变为360 x 240像素。现在运行camera .py,可以看到类似下图的显示:  4.3.3任务完成-小结  现在可以看见外部世界了!你将会使用这种视觉能力完成很多令人印象深刻的任务。  4.3.4补充信息  使用适合应用场景佳的分辨率。高分辨率固然好,因为可以提供更为细致的图像,但是也需要更多的处理能力。如果需要进行实际的图像处理,那么会有更高的要求。如果使用vnc方式来评估系统性能,要特别注意这会显著降低刷新率。一个2倍大小的图像(宽和高)需要4倍的处理能力。
上一篇: &&&&&& 下一篇:
热门排行榜
12345678910
最新学习资料
12345678910Starterware On Beaglebone Black(一) 环境搭建 - CSDN博客
Starterware On Beaglebone Black(一) 环境搭建
一,Starterware版本
Starterware是ti提供的在AM335x平台上无系统运行的套件。初看以为和ST的cubemx差不多,但是实际使用的时候仔细一看却是非常的麻烦,你必须查许多的资料,包括AM3358的寄存器文档,datasheet等等。
Starterware目前网站找得到的有两种版本,一种为官网下载的2.00.01.01版本,有一个是在sysbios_ind_sdk_2.1.0.1包里面的较为新的2.01.01.01版本,两者的区别是巨大的,2.01.01.01用起来似乎更方便而且较新,他会从板子的eeprom里面自动读取板子的信息然后判断,同时也支持官网上的pinmux工具来定义引脚,但是我个人认为实际使用还是有点冗余而且也并没有那么的方便,有兴趣的可以自行研究一下,本文会用较为老的starterware来写一个工程作为示范,当然有必要我之后也会使用新版本讲解一下的。
http://software-/dsps/dsps_public_sw/am_bu/starterware/latest/index_FDS.html
这是beaglebone的下载地址,安装好后还需要在这个地址下载一个beaglebone black的补丁,解压后覆盖即可。
二,Beaglebone Black 硬件安装
Beaglebone Black调试是有点麻烦的,首先需要买1.27的排阵焊在后面的JTAG接口上。这是我焊接的。
其次虽然Beaglebone Black 似乎可以用JLink调试但是似乎接线较为复杂,我正好有个以前DSP用的XDS100-V2,再买一个1.27转2.54的板子就能够调试了,我的转换板和排线如下:
值得一提的是,我的XDS100 引出是14pin的而标准的是20pin的,多余的pin直接忽略不接就行。
三,CCS 编译方法
在SDK的 \build\armv7a\cgt_ccs\am335x\beaglebone目录下都是针对BBB写的工工程,
随意导入一个比如GPIO的例子,然后直接编译即可。
四,ccs调试方法
首先先连接好下载器,然后按住bbb引导的那个按键,再通电,这时候会进入调试的模式,具体为什么我以后会好好讲一讲。
在硬件设计好之后,需要参考这个链接来配置一下CCS的 target。
http://processors./index.php/AM335X_StarterWare_Environment_Setup#TMS470_from_CCS_project
在这之后就可以调试了!!
之后我会以建立一个gpio中断为例,介绍一下starterware的基本结构使用方法等等,也希望各位多多指教!。
本文已收录于以下专栏:
相关文章推荐
硬件开发平台:BeagleBone A5
软件包:StarterWare_02_00_00_07
StarterWare是TI公司提供的一个支持ARM和DSP无操作系统的免费软件开发包,自然也...
文前注明:本人学生党一枚,写博文不是为了造福百姓,而是为了
StarterWare为何物,简单说是像STM32库函数一样的东西。
StarterWare for AM335X 最新下载地址:
http://software-/dsps/ds...
http://software-/sitara_linux/esd/AM335xSDK/latest/index_FDS.html
先安装SDK (刚开始...
阅读本文之前请先阅读Beaglebone Black——tslib编译与安装,先按照那篇文章做完再接着下面的步骤,本文主要记录了PC机上Qt源码的编译、BBB上Qt库的安装与配置、PC机上Qt-cre...
在Beaglebone Black上手动编译uboot、Linux内核,安装文件系统,记录了如何在Beaglebone Black上安装官方打好Xenomai 3 -patch的内核与测试。...
AM335x运用starterware裸机运行环境搭建连接到traget
AM335x运用starterware裸机运行环境搭建:
Host:win7
Target:AM335x
编译环境:C...
USB Camera on BeagleBone Black
Filed under: Uncategorized — ipeerbhai @ 3:14 am
Hello all,
...
OK, this was very straight forward with the help of Koen’s
blog and the BeagleBoard
google group...
应用开发环境一般包括cross-toolchain,文件传输或共享的方法等。
他的最新文章
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)> BeagleBone Black Linux3.8内核驱动程序开发笔记——LED驱动程序
最近这段时间在玩beaglebone-black,参照《LINUX设备驱动程序》想用来练习Linux下的驱动程序编写,于是把我最近这一个多月的学习做下笔记。我也是新手,本文仅贡交流之用,有写的不好的地方,还望各位高手指正,不吝赐教!
本文参照了:
还有其他的一些博文,对我的帮助也很大,在这就不在这一一列举了!
本文利用embest的交叉编译工具(arm-none-linux-gnueabi-)、3.8内核源码以及镜像images_svn2541(BBB-eMMC-flasher-)进行介绍
相关下载地址:
强烈建议下载说明文档:
环境搭建:
1、下载交叉编译工具
2、安装交叉编译工具
(P.S.强烈建议使用root权限进行下列操作,$ sudo -s 切换到root权限下)
①解压源文件
先进入arm--arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2所在的目录,默认是安装在/usr/local目录下的,所以解压源文件到/usr/local目录下。
$ tar -vxjf arm--arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 -C /usr/local
$ tar -vxjf arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 -C /usr/local
执行以上命令后,arm-none-linux-gnueabi-gcc安装包会被解压到/usr/local目录下的一个arm-2010.09目录中。arm-2010.09目录是在解压时自动创建的。
②设置环境变量
解压完成后,可以进入arm-2010.09目录下查看一下目录结构。其中,在/usr/local/arm-2010.09/bin/目录下存放的是交叉编译工具的各命令。为了使系统能够找到交叉编译工具的各命令,可以将/usr/local/arm-2010.09/bin/目录增加到PATH变量中。步骤如下:
打开/etc/bash.bashrc脚本
$ gedit /etc/bash.bashrc
$ gedit /etc/bash.bashrc
在文件的末尾最后添加一行,来增加一个环境变量。
export PATH=$PATH:/usr/local/arm-2010.09/bin/
export PATH=$PATH:/usr/local/arm-2010.09/bin/
保存退出。
尽管增加了交叉编译工具的路径,并且保存了/etc/bash.bashrc脚本,但是,由于修改后,没有执行,因此修改后的PATH变量没有起作用,必须手动执行一次/etc/bash.bashrc脚本。
$ source /etc/bash.bashrc
$ source /etc/bash.bashrc
当然,也可以重启系统,因为,系统启动时,会自动执行该脚本。
验证,打开一个新终端执行:
$ echo $PATH
$ echo $PATH
如果有”/usr/local/arm-2010.09/bin/”则说明添加成功。
注:64位操作系统需要执行以下命令来安装所需的库文件以运行32位交叉编译工具链:
$ sudo apt-get install ia32-libs
在终端中执行:
$ arm-none-linux-gnueabi-gcc --version
$ arm-none-linux-gnueabi-gcc --version
如果显示出来交叉编译器的版本号出来则安装成功
3、更新Beaglebone Black的版本
(P.S.强烈建议按照《BeagleBone Black用户手册》操作进行更新)
①准备:映像文件(BBB-eMMC-flasher-.img.xz)、、、4G以上的SD卡。
②使用7-zip压缩工具解压刚才下载的映像文件;
③用一个MicroSD卡套或者USB读卡器将一张MicroSD卡连接到PC;
④使用刚才安装的Win32 Disk ImagerDisk Imager工具将解压后映像文件写入MicroSD卡;
⑤将MicroSD卡插入BeagleBone Black的卡槽中,然后按住uSD BOOT按钮并使用USB线缆接通电源;
⑥当4个User LED同时持续亮起,表示已成功完系统更新(需耗45分钟左右)。请断开电源并取出MicroSD卡,然后再次接通电源即可。
4、编译内核
(P.S.强烈建议按照《BeagleBone Black用户手册》操作进行更新)
准备:Linux3.8内核源码
先自行解压,之后执行以下命令来编译内核;
$ cd ~/kernel/kernel
$ cp ../configs/beaglebone .config
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage dtbs
$ cd ~/kernel/kernel$ cp ../configs/beaglebone .config$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage dtbs
注意:如果编译内核过程中出现/bin/sh: lzop:command not found的错误,在Ubuntu系统下,使用命令$ sudo apt-get install lzop 安装lzop包。
驱动编译:
1、内核空间
驱动程序gpioCtl.c:
#include &linux/module.h&
#include &linux/kernel.h&
#include &linux/printk.h&
#include &linux/fs.h&
#include &linux/cdev.h&
#include &linux/init.h&
#include &linux/i2c.h&
#include &linux/delay.h&
#include &linux/gpio.h&
#include &linux/slab.h&
#include &asm/uaccess.h&
/*-----------------------------------------------------*/
#define DEVICE_NAME
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))
/*------------------------------------------------------*/
struct gpio_
/*设备编号存储结构体*/
struct dev_num
dev_t devN
unsigned int minor_
struct dev_num gpio_dev_
/*设备描述结构体*/
struct gpio_dev
struct gpio_qset*
//设备数据存储链表第一项
//链表长度(随着申请的GPIO端口数增长)
struct gpio_dev *gpio_
/*设备数据存储结构体(采用链式存储,不理解的可以看《数据结构》)*/
struct gpio_qset
//端口号 #define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))
//方向(输入(0)或输出(1))
//高(1)低(0)电平
//当前编号(按照申请顺序编号)
char label[10];
//申请的GPIO使用名称
struct gpio_qset*
//指向链表下一项的指针
* 功能:初始化gpio_dev
* 描述:用户空间调用open时运行
int (*open) (struct inode *, struct file *);
* 返回值:0
static int gpio_open(struct inode *inode, struct file *filp)
struct gpio_dev *
//由container_of获得结构体指针inode中结构体cdev的指针,
//让结构体指针dev指向上述的指针所指的地址,
//再让file-&private指向这一地址,
dev = container_of(inode-&i_cdev, struct gpio_dev, cdev);
filp-&private_data =
dev-&dptr = NULL;
dev-&size = 0;
//printk(KERN_ERR "gpio_open success!\n");
* 功能:释放申请的GPIO端口以及释放链表(gpio_qset)
* 描述:用户空间调用close时运行
int (*release) (struct inode *, struct file *);
* 返回值:0
static int gpio_close(struct inode *inode, struct file *filp)
struct gpio_dev *dev = filp-&private_
struct gpio_qset *qset, *qsetT
qsetTmp = (struct gpio_qset *)kzalloc(sizeof(struct gpio_qset), GFP_KERNEL);
for(qset = dev-& qset-&next !=NULL; qset=qsetTmp)
qsetTmp = qset-&
gpio_free(qset-&port);
//释放申请的端口
kfree(qset);
//释放gpio_qset内存
gpio_free(qsetTmp-&port);
kfree(qsetTmp);
//printk(KERN_ERR "gpio release!\n");
* 功能:申请新的gpio_qset的内存,确定相应的GPIO端口功能
* cmd:实现的功能,
2:释放GPIO端口
* arg:执行操作的GPIO端口
* 描述:用户空间调用ioctl时运行
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
* 返回值:成功返回操作的GPIO端口号
错误返回相应的错误码
static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
struct gpio_dev *dev = filp-&private_
struct gpio_qset *
//cmd == 2 设计成为释放arg端口的功能,之后申请内存的任务便不必执行了,所以直接返回
if(cmd == 2)
gpio_free(arg);
dev-&size++;
if(dev-&dptr == NULL)
dev-&dptr = (struct gpio_qset *)kzalloc(sizeof(struct gpio_qset), GFP_KERNEL);
qset = dev-&
for(qset = dev-& qset-&next != NULL; qset = qset-&next);
//找到链表最后一项
qset-&next = (struct gpio_qset *)kzalloc(sizeof(struct gpio_qset), GFP_KERNEL);
qset = qset-&
/*链表数据*/
qset-&num = dev-&
//确定自己的编号
qset-&ddr =
//确定方向
qset-&port =
//确定端口号
qset-&next = NULL;
//最后一项地址清空
//printk(KERN_ERR "qset-&num=%d,qset-&ddr=%d,qset-&port=%d\n", qset-&num, qset-&ddr, qset-&port);
sprintf(qset-&label, "gpio%ld", qset-&port);
//确定申请的GPIO使用名称(和端口直接相关)
ret = gpio_request(qset-&port, qset-&label);
//申请端口
/*由于gpio_requset会自己判断成功与否并且退出函数,故注释掉对ret的判断
if(ret & 0)
printk(KERN_ERR "%s_requset failled!%d \n", qset-&label, ret);
/*判断GPIO工作方向(输出或输出)*/
switch(qset-&ddr)
ret = gpio_direction_input(qset-&port);
if(ret & 0)
printk(KERN_ERR "gpio_direction_input failled!\n");
ret = gpio_direction_output(qset-&port, 1);
if(ret & 0)
printk(KERN_ERR "gpio_direction_output failled!\n");
return -EPERM;
/* Operation not permitted */
return qset-&
* 功能:获取相应端口电平,写入相应的qset_dev-&value,写到用户空间的readBuf
* *readBuf:读数据缓存指针,用户空间的指针
* port:被读取的GPIO端口号
* 描述:用户空间调用read时运行
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
* 返回值:成功返回qset-&value
错误返回相应的错误码
static ssize_t gpio_read (struct file *filp, char __user *readBuf, size_t port, loff_t *offp)
struct gpio_dev *dev = filp-&private_
struct gpio_qset *
if(dev-&dptr == NULL)
return -ENODEV;
/* No such device */
for(qset = dev-& qset != NULL; qset = qset-&next)
if(qset-&port == port)
if(qset-&next == NULL)
return -ENODEV;
/* No such device */
if(qset-&ddr != 0)
//判断是否ioctl设置为读操作
return -EPERM;
/* Operation not permitted */
qset-&value = gpio_get_value(qset-&port);
//printk(KERN_ERR "qset-&port:%d, qset-&value:%d\n", qset-&port, qset-&value);
switch(qset-&value)
ret = copy_to_user(readBuf, "0", 1);
ret = copy_to_user(readBuf, "1", 1);
return qset-&
* 功能:写入相应端口电平,写入相应的qset_dev-&value,数据来自用户空间的writeBuf
* *writeBuf:写数据缓存指针,用户空间的指针
* port:被写入的GPIO端口号
* 描述:用户空间调用write时运行
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
* 返回值:成功返回qset-&value
错误返回相应的错误码
static ssize_t gpio_write (struct file *filp, const char __user *writeBuf, size_t port, loff_t *offp)
struct gpio_dev *dev = filp-&private_
struct gpio_qset *
if(dev-&dptr == NULL)
return -ENODEV;
/* No such device */
for(qset = dev-& qset != NULL; qset = qset-&next)
printk(KERN_ERR "qset-&port=%d,port=%d\n", qset-&port, port);
if(qset-&port == port)
if(qset-&next == NULL)
return -ENODEV;
/* No such device */
if(qset-&ddr != 1)
//判断是否ioctl设置为写操作
return -EPERM;
/* Operation not permitted */
ret = copy_from_user(&qset-&value, writeBuf, 1);
//printk(KERN_ERR "write:%d\n", qset-&value);
switch(qset-&value)
case '0': qset-&value = 0;
gpio_set_value(qset-&port, 0);
default : qset-&value = 1;
gpio_set_value(qset-&port, 1);
return qset-&
/*文件操作结构体*/
static const struct file_operations gpio_fops = {
.owner = THIS_MODULE,
.open = gpio_open,
.unlocked_ioctl = gpio_ioctl,
.write = gpio_write,
.read = gpio_read,
.release = gpio_close,
/*cdev注册函数*/
static void gpio_setup_cdev(struct gpio_dev *dev, int index)
int ret,devno = gpio_dev_num.devNum +
cdev_init(&dev-&cdev, &gpio_fops);
dev-&cdev.owner = THIS_MODULE;
dev-&cdev.ops = &gpio_
ret = cdev_add(&dev-&cdev, devno, 1);
printk(KERN_ERR "error %d : adding gpioCtl%d",ret,index);
/*设备初始化函数*/
static int __init omap3gpio_init(void)
gpio_dev_num.count = 1;
gpio_dev_num.minor_first = 0;
ret = alloc_chrdev_region(&gpio_dev_num.devNum, gpio_dev_num.minor_first, gpio_dev_num.count, DEVICE_NAME);
if(ret & 0)
gpio_dev_num.major = MAJOR(gpio_dev_num.devNum);
gpio_dev_num.minor = MINOR(gpio_dev_num.devNum);
gpio_devp = kzalloc(sizeof(struct gpio_dev),GFP_KERNEL);
gpio_setup_cdev(gpio_devp, 0);
printk(KERN_ERR "gpio alloc_chrdev_region success, major = %d\n", gpio_dev_num.major);
/*设备释放函数*/
static void __exit omap3gpio_exit(void)
//struct file *
//struct inode *
//inode = container_of(&gpio_devp-&cdev, struct inode, i_cdev);
//filp = container_of(gpio_devp, struct file, private_data);
//gpio_close(inode, filp);
cdev_del(&gpio_devp-&cdev);
kfree(gpio_devp);
unregister_chrdev_region(gpio_dev_num.devNum, 1);
printk(KERN_ERR "gpio unregister_chrdev_region success, major = %d\n", gpio_dev_num.major);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Mlo_Lv,Tute-421E-studio");
MODULE_DESCRIPTION("This module is used to conrtol omap3 gpio");
module_init(omap3gpio_init);
module_exit(omap3gpio_exit);
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
#include &linux/module.h&#include &linux/kernel.h&#include &linux/printk.h&#include &linux/fs.h&#include &linux/cdev.h&#include &linux/init.h&#include &linux/i2c.h&#include &linux/delay.h&#include &linux/gpio.h&#include &linux/slab.h&#include &asm/uaccess.h&/*-----------------------------------------------------*/#define DEVICE_NAME&&&&&&&&"gpioCtl"#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))/*------------------------------------------------------*/&struct gpio_qset;&/*设备编号存储结构体*/struct dev_num{&&&&&&&&dev_t devNum;&&&&&&&&unsigned int major;&&&&&&&&unsigned int minor;&&&&&&&&unsigned int minor_first;&&&&&&&&unsigned int count;};struct dev_num gpio_dev_num;&/*设备描述结构体*/struct gpio_dev{&&&&&&&&struct cdev cdev;&&&&&&&&struct gpio_qset* dptr;&&&&&&&&//设备数据存储链表第一项&&&&&&&&unsigned long size;&&&&&&&&//链表长度(随着申请的GPIO端口数增长)};struct gpio_dev *gpio_devp;&/*设备数据存储结构体(采用链式存储,不理解的可以看《数据结构》)*/struct gpio_qset{&&&&&&&&unsigned long port;&&&&&&&&//端口号 #define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))&&&&&&&&unsigned int ddr;&&&&&&&&//方向(输入(0)或输出(1))&&&&&&&&char value;&&&&&&&&&&&&&&&&//高(1)低(0)电平&&&&&&&&unsigned long num;&&&&&&&&//当前编号(按照申请顺序编号)&&&&&&&&char label[10];&&&&&&&&&&&&&&&&//申请的GPIO使用名称&&&&&&&&struct gpio_qset* next;&&&&&&&&//指向链表下一项的指针};&/** * 功能:初始化gpio_dev * *inode: * *filp: * 描述:用户空间调用open时运行 *&&&&&&&& int (*open) (struct inode *, struct file *); * 返回值:0 */static int gpio_open(struct inode *inode, struct file *filp){&&&&&&&&struct gpio_dev *dev;&&&&&&&&&//由container_of获得结构体指针inode中结构体cdev的指针,&&&&&&&&//让结构体指针dev指向上述的指针所指的地址,&&&&&&&&//再让file-&private指向这一地址,&&&&&&&&dev = container_of(inode-&i_cdev, struct gpio_dev, cdev);&&&&&&&&filp-&private_data = dev;&&&&&&&&dev-&dptr = NULL;&&&&&&&&dev-&size = 0;&&&&&&&&//printk(KERN_ERR "gpio_open success!\n");&&&&&&&&return 0;}&/** * 功能:释放申请的GPIO端口以及释放链表(gpio_qset) * *inode: * *filp: * 描述:用户空间调用close时运行 *&&&&&&&& int (*release) (struct inode *, struct file *); * 返回值:0 */static int gpio_close(struct inode *inode, struct file *filp){&&&&&&&&struct gpio_dev *dev = filp-&private_data;&&&&&&&&struct gpio_qset *qset, *qsetTmp;&&&&&&&&qsetTmp = (struct gpio_qset *)kzalloc(sizeof(struct gpio_qset), GFP_KERNEL);&&&&&&&&for(qset = dev-&dptr; qset-&next !=NULL; qset=qsetTmp)&&&&&&&&{&&&&&&&&&&&&&&&&qsetTmp = qset-&next;&&&&&&&&&&&&&&&&gpio_free(qset-&port);&&&&&&&&//释放申请的端口&&&&&&&&&&&&&&&&kfree(qset);&&&&&&&&&&&&&&&&//释放gpio_qset内存&&&&&&&&}&&&&&&&&gpio_free(qsetTmp-&port);&&&&&&&&kfree(qsetTmp);&&&&&&&& //printk(KERN_ERR "gpio release!\n");&&&&&&&&return 0;}&/** * 功能:申请新的gpio_qset的内存,确定相应的GPIO端口功能 * *inode: * *filp: * cmd:实现的功能, *&&&& 0:读, *&&&& 1:写, *&&&& 2:释放GPIO端口 * arg:执行操作的GPIO端口 * 描述:用户空间调用ioctl时运行 *&&&&&&&& long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); * 返回值:成功返回操作的GPIO端口号 *&&&&&&&&&& 错误返回相应的错误码 */static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){&&&&&&&&int ret;&&&&&&&&struct gpio_dev *dev = filp-&private_data;&&&&&&&&struct gpio_qset *qset;&&&&&&&&&//cmd == 2 设计成为释放arg端口的功能,之后申请内存的任务便不必执行了,所以直接返回&&&&&&&&if(cmd == 2)&&&&&&&&{&&&&&&&&&&&&&&&&gpio_free(arg);&&&&&&&&&&&&&&&&return arg;&&&&&&&&}&&&&&&&&&dev-&size++;&&&&&&&&&if(dev-&dptr == NULL)&&&&&&&&{&&&&&&&&&&&&&&&&dev-&dptr = (struct gpio_qset *)kzalloc(sizeof(struct gpio_qset), GFP_KERNEL);&&&&&&&&&&&&&&&&qset = dev-&dptr;&&&&&&&&}&&&&&&&&else&&&&&&&&{&&&&&&&&&&&&&&&&for(qset = dev-&dptr; qset-&next != NULL; qset = qset-&next);&&&&&&&&&&&&&&&&&&&&&&&&//找到链表最后一项&&&&&&&&&&&&&&&&qset-&next = (struct gpio_qset *)kzalloc(sizeof(struct gpio_qset), GFP_KERNEL);&&&&&&&&&&&&&&&&qset = qset-&next;&&&&&&&&}&&&&&&&&/*链表数据*/&&&&&&&&qset-&num = dev-&size;&&&&&&&&//确定自己的编号&&&&&&&&qset-&ddr = cmd;&&&&&&&&//确定方向&&&&&&&&qset-&port = arg;&&&&&&&&//确定端口号&&&&&&&&qset-&next = NULL;&&&&&&&&//最后一项地址清空&&&&&&&&&//printk(KERN_ERR "qset-&num=%d,qset-&ddr=%d,qset-&port=%d\n", qset-&num, qset-&ddr, qset-&port);&&&&&&&&sprintf(qset-&label, "gpio%ld", qset-&port);&&&&&&&&&&&&&&&&//确定申请的GPIO使用名称(和端口直接相关)&&&&&&&&ret = gpio_request(qset-&port, qset-&label);&&&&&&&&&&&&&&&&//申请端口&&&&&&&&&/*由于gpio_requset会自己判断成功与否并且退出函数,故注释掉对ret的判断&&&&&&&&if(ret & 0)&&&&&&&&&&&&&&&&printk(KERN_ERR "%s_requset failled!%d \n", qset-&label, ret);&&&&&&&&*/&&&&&&&&&/*判断GPIO工作方向(输出或输出)*/&&&&&&&&&&&&&&&&switch(qset-&ddr)&&&&&&&&{&&&&&&&&&&&&&&&&case 0:&&&&&&&&ret = gpio_direction_input(qset-&port);&&&&&&&&&&&&&&&&&&&&&&&&if(ret & 0)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&printk(KERN_ERR "gpio_direction_input failled!\n");&&&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&&&case 1:&&&&&&&&ret = gpio_direction_output(qset-&port, 1);&&&&&&&&&&&&&&&&&&&&&&&&if(ret & 0)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&printk(KERN_ERR "gpio_direction_output failled!\n");&&&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&&&default:&&&&&&&&&&&&&&&&&&&&&&&&return -EPERM;&&&&&&&&/* Operation not permitted */&&&&&&&&}&&&&&&&&return qset-#}&/** * 功能:获取相应端口电平,写入相应的qset_dev-&value,写到用户空间的readBuf * *inode: * *filp: * *readBuf:读数据缓存指针,用户空间的指针 * port:被读取的GPIO端口号 * *offp: * 描述:用户空间调用read时运行 *&&&&&&&& ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); * 返回值:成功返回qset-&value *&&&&&&&&&& 错误返回相应的错误码 */static ssize_t gpio_read (struct file *filp, char __user *readBuf, size_t port, loff_t *offp){&&&&&&&&long ret;&&&&&&&&struct gpio_dev *dev = filp-&private_data;&&&&&&&&struct gpio_qset *qset;&&&&&&&&&if(dev-&dptr == NULL)&&&&&&&&&&&&&&&&&&&&&&&&return -ENODEV;&&&&&&&&&&&&&&&&/* No such device */&&&&&&&&&for(qset = dev-&dptr; qset != NULL; qset = qset-&next)&&&&&&&&{&&&&&&&&&&&&&&&&if(qset-&port == port)&&&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&&&if(qset-&next == NULL)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return -ENODEV;&&&&&&&&/* No such device */&&&&&&&&}&&&&&&&&&if(qset-&ddr != 0)&&&&&&&&&&&&&&&&//判断是否ioctl设置为读操作&&&&&&&&&&&&&&&&return -EPERM;&&&&&&&&&&&&&&&&/* Operation not permitted */&&&&&&&&qset-&value = gpio_get_value(qset-&port);&&&&&&&&//printk(KERN_ERR "qset-&port:%d, qset-&value:%d\n", qset-&port, qset-&value);&&&&&&&&switch(qset-&value)&&&&&&&&{&&&&&&&&&&&&&&&&case 0:&&&&&&&&ret = copy_to_user(readBuf, "0", 1);&&&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&&&case 1:&&&&&&&&ret = copy_to_user(readBuf, "1", 1);&&&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&}&&&&&&&&return qset-&value;}/** * 功能:写入相应端口电平,写入相应的qset_dev-&value,数据来自用户空间的writeBuf * *inode: * *filp: * *writeBuf:写数据缓存指针,用户空间的指针 * port:被写入的GPIO端口号 * *offp: * 描述:用户空间调用write时运行 *&&&&&&&& ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); * 返回值:成功返回qset-&value *&&&&&&&&&& 错误返回相应的错误码 */static ssize_t gpio_write (struct file *filp, const char __user *writeBuf, size_t port, loff_t *offp){&&&&&&&&long ret;&&&&&&&&struct gpio_dev *dev = filp-&private_data;&&&&&&&&struct gpio_qset *qset;&&&&&&&&&if(dev-&dptr == NULL)&&&&&&&&&&&&&&&&&&&&&&&&return -ENODEV;&&&&&&&&&&&&&&&&/* No such device */&&&&&&&&&for(qset = dev-&dptr; qset != NULL; qset = qset-&next)&&&&&&&&{&&&&&&&&//&&&&&&&&printk(KERN_ERR "qset-&port=%d,port=%d\n", qset-&port, port);&&&&&&&&&&&&&&&&if(qset-&port == port)&&&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&&&if(qset-&next == NULL)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return -ENODEV;&&&&&&&&/* No such device */&&&&&&&&}&&&&&&&&&if(qset-&ddr != 1)&&&&&&&&&&&&&&&&//判断是否ioctl设置为写操作&&&&&&&&&&&&&&&&return -EPERM;&&&&&&&&&&&&&&&&/* Operation not permitted */ &&&&&&&&&ret = copy_from_user(&qset-&value, writeBuf, 1);&&&&&&&&//printk(KERN_ERR "write:%d\n", qset-&value);&&&&&&&&switch(qset-&value)&&&&&&&&{&&&&&&&&&&&&&&&&case '0': qset-&value = 0;&&&&&&&&&&&&&&&&&&&&&&&&&&gpio_set_value(qset-&port, 0);&&&&&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&&&default : qset-&value = 1;&&&&&&&&&&&&&&&&&&&&&&&&&&gpio_set_value(qset-&port, 1);&&&&&&&&&&&&&&&&&&&&&&&&&&break;&&&&&&&&}&&&&&&&&return qset-&value;}&/*文件操作结构体*/static const struct file_operations gpio_fops = {&&&&&&&&.owner = THIS_MODULE,&&&&&&&&.open = gpio_open,&&&&&&&&.unlocked_ioctl = gpio_ioctl,&&&&&&&&.write = gpio_write,&&&&&&&&.read = gpio_read,&&&&&&&&.release = gpio_close,};&/*cdev注册函数*/static void gpio_setup_cdev(struct gpio_dev *dev, int index){&&&&&&&&int ret,devno = gpio_dev_num.devNum + index;&&&&&&&&cdev_init(&dev-&cdev, &gpio_fops);&&&&&&&&dev-&cdev.owner = THIS_MODULE;&&&&&&&&dev-&cdev.ops = &gpio_fops;&&&&&&&&&ret = cdev_add(&dev-&cdev, devno, 1);&&&&&&&&&if(ret)&&&&&&&&&&&&&&&&printk(KERN_ERR "error %d : adding gpioCtl%d",ret,index);}&/*设备初始化函数*/static int __init omap3gpio_init(void){&&&&&&&&int ret;&&&&&&&&&gpio_dev_num.count = 1;&&&&&&&&gpio_dev_num.minor_first = 0;&&&&&&&&ret = alloc_chrdev_region(&gpio_dev_num.devNum, gpio_dev_num.minor_first, gpio_dev_num.count, DEVICE_NAME);&&&&&&&&&if(ret & 0)&&&&&&&&&&&&&&&&&&&&&&&&return ret;&&&&&&&&&gpio_dev_num.major = MAJOR(gpio_dev_num.devNum);&&&&&&&&gpio_dev_num.minor = MINOR(gpio_dev_num.devNum);&&&&&&&&&gpio_devp = kzalloc(sizeof(struct gpio_dev),GFP_KERNEL);&&&&&&&&&gpio_setup_cdev(gpio_devp, 0);&&&&&&&&&printk(KERN_ERR "gpio alloc_chrdev_region success, major = %d\n", gpio_dev_num.major);&&&&&&&&return 0;}&/*设备释放函数*/static void __exit omap3gpio_exit(void){&&&&&&&&/*test*/&&&&&&&&//struct file *&&&&&&&&//struct inode *&&&&&&&&//inode = container_of(&gpio_devp-&cdev, struct inode, i_cdev);&&&&&&&&//filp = container_of(gpio_devp, struct file, private_data);&&&&&&&&//gpio_close(inode, filp);&&&&&&&&/*test*/&&&&&&&&&cdev_del(&gpio_devp-&cdev);&&&&&&&&kfree(gpio_devp);&&&&&&&&unregister_chrdev_region(gpio_dev_num.devNum, 1);&&&&&&&&printk(KERN_ERR "gpio unregister_chrdev_region success, major = %d\n", gpio_dev_num.major);}&MODULE_LICENSE("Dual BSD/GPL");MODULE_AUTHOR("Mlo_Lv,Tute-421E-studio");MODULE_DESCRIPTION("This module is used to conrtol omap3 gpio");&module_init(omap3gpio_init);module_exit(omap3gpio_exit);
我的驱动程序文件名是gpioCtl.c,如果各位想直接使用这一驱动的话,请使用这个文件名,不要修改。还有就是其中对于GPIO操作的一些函数,例如”gpio_requset()”,”gpio_free()”,”gpio_set_value()”,如果有不理解的可以参照:http://blog.csdn.net/beyondioi/article/details/6984406,这篇博文详细讲解了omap系列产品用于操作GPIO的函数,其实看看源码应该能够明白这写函数的意思。
Makefile:
#Makefile for gpioCtl.c
CROSS_COMPILE=arm-none-linux-gnueabi-
ifneq ($(KERNELRELEASE),)
obj-m := gpioCtl.o
KERNELDIR ?= /beaglebone/bbb/kernel/kernel
PWD := $(shell pwd)
make -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
app: app.c
$(CROSS_COMPILE)gcc -o app app.c
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
rm -rf modules.order
12345678910111213141516171819
#Makefile for gpioCtl.cARCH=armCROSS_COMPILE=arm-none-linux-gnueabi-ifneq ($(KERNELRELEASE),) obj-m := gpioCtl.oelse
KERNELDIR ?= /beaglebone/bbb/kernel/kernel PWD := $(shell pwd)default: make -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules&app: app.c $(CROSS_COMPILE)gcc -o app app.cclean: $(MAKE) -C $(KERNELDIR) M=$(PWD) clean rm -rf modules.ordercleanr: rm *~endif
如果各位使用的交叉编译器和我的不一样的话,请修改CROSS_COMPILE(一样的话就免了),然后修改KERNELDIR成为自己内核的存储路径,至此所有有关驱动的程序就写完了,将上面的两短代码放在同一文件目录下,make(编译驱动之前,请先编译好内核),就会生成相应的驱动gpioCtl.ko
2、用户空间
应用程序app.c:
#include &stdio.h&
#include &stdlib.h&
#include &sys/types.h&
#include &sys/stat.h&
#include &fcntl.h&
#include &linux/input.h&
#include &unistd.h&
#include &sys/ioctl.h&
#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))
int main(int argc, char * argv)
fd = open("/dev/gpioCtl", O_RDWR);
//打开设备
if (fd & 0)
printf("can't open /dev/gpioCtl!\n");
ioctl(fd, 1, GPIO_TO_PIN(1,22));
//设置gpio1-22为输出(user:led3)
ioctl(fd, 0, GPIO_TO_PIN(2, 1));
//设置gpio2-1 为输入(p8-18)
ret = write(fd,"1",GPIO_TO_PIN(1,22));
printf("on");
if(ret & 0)
perror("write");
return -1;
ret = write(fd,"0",GPIO_TO_PIN(1,22));
printf("off");
if(ret & 0)
perror("write");
return -1;
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
#include &stdio.h&#include &stdlib.h&#include &sys/types.h&#include &sys/stat.h&#include &fcntl.h&#include &linux/input.h&#include &unistd.h&#include &sys/ioctl.h&&#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))&int main(int argc, char * argv){&&&&&&&&int i, n, fd;&&&&&&&&char num;&&&&&&&&int ret;&&&&&&&&fd = open("/dev/gpioCtl", O_RDWR);&&&&&&&&&&&&&&&&//打开设备&&&&&&&&if (fd & 0)&&&&&&&&{&&&&&&&&&&&&printf("can't open /dev/gpioCtl!\n");&&&&&&&&&&&&exit(1);&&&&&&&&}&&&&&&&&sleep(1);&&&&&&&&ioctl(fd, 1, GPIO_TO_PIN(1,22));&&&&&&&&&&&&&&&&//设置gpio1-22为输出(user:led3)&&&&&&&&ioctl(fd, 0, GPIO_TO_PIN(2, 1));&&&&&&&&&&&&&&&&//设置gpio2-1 为输入(p8-18)&&&&&&&&while (1) &&&&&&&&{&&&&&&&&&&&&&&&&num = 1;&&&&&&&&&&&&&&&&ret = write(fd,"1",GPIO_TO_PIN(1,22)); printf("on");&&&&&&&&&&&&&&&&if(ret & 0)&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&perror("write");&&&&&&&&&&&&&&&&&&&&&&&&return -1;&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&sleep(1);&&&&&&&&&&&&&&&&ret = write(fd,"0",GPIO_TO_PIN(1,22)); printf("off");&&&&&&&&&&&&&&&&if(ret & 0)&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&perror("write");&&&&&&&&&&&&&&&&&&&&return -1; } sleep(1); }}
执行”$ make app”交叉编译应用程序。此程序能实现user:led3闪烁效果以及读取gpio2-1的电平!
gpioCtl.sh:
insmod gpioCtl.ko
mknod /dev/gpioCtl c 241 0
#!/bin/shinsmod gpioCtl.komknod /dev/gpioCtl c 241 0
我在上面的驱动程序编号申请采用动态分配方式,但是每次分配的主设备号都是241,所以shell中的设备号采用了241,如果各位动态分配的结果不是241,可能需要修改shell,cat /proc/devices 可以察看到分配到的设备号。
3、运行测试
现在将所有文件拷贝到板子上
可以用SSH拷贝,利用”$ scp 源文件 root@192.168.7.2:目标目录”命令进行拷贝
在beaglebone black终端上运行以下命令进行测试:
#为脚本增加执行权
$ chmod +x gpioCtl.sh
#运行脚本,挂载驱动
./gpioCtl.sh
#运行测试程序,控制LED3灯每隔1秒闪烁
#为脚本增加执行权$ chmod +x gpioCtl.sh#运行脚本,挂载驱动./gpioCtl.sh#运行测试程序,控制LED3灯每隔1秒闪烁./app
如果没有问题的话,现在就能看到 led 闪烁了!
关注公众号,定期推送精彩内容!
如未说明则本站原创,转载请注明出处: >>

我要回帖

更多关于 fishbone 的文章

 

随机推荐