|
本帖最后由 glqinhan 于 2010-11-26 16:48 编辑
大家好,在学习Qt4.7的移植时按照TQ6410_QT4.7移植手册的Led测试例程开发,目标板是TQ2440,使用内核EmbedSky-leds为设备文件,改变LED1 ——LED4的状态时开发板上的LED不受控制。
界面程序如下:
#include "ledtest.h"
#include "ui_ledtest.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<string.h>
#include <sys/ioctl.h>
#include<stdio.h>
#include<QDirectPainter>
static int fb;
static int LED1=0, LED2=0,LED3=0,LED4=0;
ledtest::ledtest(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ledtest)
{
ui->setupUi(this);
int screenWidth=QDirectPainter::screenWidth();
int screenHeight=QDirectPainter::screenHeight();
this->resize(screenWidth,screenHeight);
connect(ui->checkBox_LED1,SIGNAL(toggled(bool)),this,SLOT(LED1_Toggle()));
connect(ui->checkBox_LED2,SIGNAL(toggled(bool)),this,SLOT(LED2_Toggle()));
connect(ui->checkBox_LED3,SIGNAL(toggled(bool)),this,SLOT(LED3_Toggle()));
connect(ui->checkBox_LED4,SIGNAL(toggled(bool)),this,SLOT(LED4_Toggle()));
system("/etc/rc.d/init.d/leds stop");
fb=open("/dev/EmbedSky-leds",O_RDWR);
if(fb<0)
{
perror("open device leds fail");
exit(1);
}
for (int i = 0 ; i < 4; i ++)
{
ioctl(fb, 0, i);
}
}
ledtest::~ledtest()
{
delete ui;
}
void ledtest::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent:: LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void ledtest:: LED1_Toggle()
{
LED1=~LED1;
ui->textBrowser->setText("LED1_Toggle\n");
if(LED1==1)
{
ioctl(fb,1,0);
}
else
{
ioctl(fb,0,0);
}
}
void ledtest:: LED2_Toggle()
{
LED2=~LED2;
ui->textBrowser->setText("LED2_Toggle\n");
if(LED2==1)
{
ioctl(fb,1,1);
}
else
{
ioctl(fb,0,1);
}
}
void ledtest:: LED3_Toggle()
{
LED3=~LED3;
ui->textBrowser->setText("LED3_Toggle\n");
if(LED3==1)
{
ioctl(fb,1,2);
}
else
{
ioctl(fb,0,2);
}
}
void ledtest:: LED4_Toggle()
{
LED4=~LED4;
ui->textBrowser->setText("LED4_Toggle\n");
if(LED4==1)
{
ioctl(fb,1,3);
}
else
{
ioctl(fb,0,3);
}
}
LED驱动EmbedSky_leds.ko是通过TQ的linux-2.6.30.4中drivers/char/EmbedSky_gpio.c修改为EmbedSky_leds.c编译而成(具体操作按天嵌科技出品-Linux移植之Step By Step_V4.5_20100605的5.2节来完成的)源码为:
/**************************************
NAME:EmbedSky_leds.c
COPYRIGHT:www.embedsky.net
*************************************/
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <linux/device.h>
#define DEVICE_NAME "EmbedSky-leds" /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */
#define LED_MAJOR 231 /* 主设备号 */
/* 应用程序执行 ioctl(fd, cmd, arg)时的第 2 个参数 */
#define IOCTL_LED_ON 1
#define IOCTL_LED_OFF 0
/* 用来指定 LED 所用的 GPIO 引脚 */
static unsigned long led_table [] =
{
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
S3C2410_GPB8,
};
/* 用来指定 GPIO 引脚的功能:输出 */
static unsigned int led_cfg_table [] =
{
S3C2410_GPB5_OUTP,
S3C2410_GPB6_OUTP,
S3C2410_GPB7_OUTP,
S3C2410_GPB8_OUTP,
};
/* 应用程序对设备文件/dev/EmbedSky-leds 执行 open(...)时,
* 就会调用 EmbedSky_leds_open 函数*/
static int EmbedSky_leds_open(struct inode *inode, struct file *file)
{
return 0;
}
/* 应用程序对设备文件/dev/EmbedSky-leds 执行 ioclt(...)时,
* 就会调用 EmbedSky_leds_ioctl 函数
*/
static int EmbedSky_leds_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
if (arg > 4)
{
return -EINVAL;
}
switch(cmd)
{
case IOCTL_LED_ON:
// 设置指定引脚的输出电平为 0
s3c2410_gpio_setpin(led_table[arg], 0);
return 0;
case IOCTL_LED_OFF:
// 设置指定引脚的输出电平为 1
s3c2410_gpio_setpin(led_table[arg], 1);
return 0;
default:
return -EINVAL;
}
}
/* 这个结构是字符设备驱动程序的核心
* 当应用程序操作设备文件时所调用的 open、read、write 等函数,
* 最终会调用这个结构中指定的对应函数
*/
static struct file_operations EmbedSky_leds_fops =
{
/* 这是一个宏,推向编译模块时自动创建的__this_module 变量 */
.owner = THIS_MODULE,
.open = EmbedSky_leds_open,
.ioctl = EmbedSky_leds_ioctl,
};
static char __initdata banner[] = "TQ2440/SKY2440 LEDS, (c) 2008,2009 www.embedsky.net\n";
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &EmbedSky_leds_fops,
};
/*
* 执行“insmod EmbedSky_leds.ko”命令时就会调用这个函数
*/
static int __init EmbedSky_leds_init(void)
{
int ret;
int i;
for (i = 0; i < 4; i++)
{
s3c2410_gpio_cfgpin(led_table, led_cfg_table);
s3c2410_gpio_setpin(led_table, 0);
}
printk(banner);
ret = misc_register(&misc);
printk(DEVICE_NAME " initialized\n");
return 0;
}
/*
* 执行”rmmod EmbedSky_leds.ko”命令时就会调用这个函数
*/
static void __exit EmbedSky_leds_exit(void)
{
misc_deregister(&misc); //注销类
}
/* 这两行指定驱动程序的初始化函数和卸载函数 */
module_init(EmbedSky_leds_init);
module_exit(EmbedSky_leds_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("EmbedSky");
MODULE_DESCRIPTION("LED control for EmbedSky SKY2440/TQ2440 Board");
生成EmbedSky_leds.ko后,复制到目标板,安装后在目标板的/dev下生成了EmbedSky-leds,在运行Qt LED测试程序LedTest,开发板上LED全灭,界面上改变LED1--LED4的状态,开发板上的LED灯没反应。
请高手指点! |
|