linux下点灯问题

九个太阳2023 2010-09-29 10:26:45
硬件平台:OMAP-L138
软件平台:linux-2.6.32+VMware

问题描述:
板子上有个CPLD,CPLD的逻辑关系开发商不给,只给了文档描述,如下:


我自己写了个字符驱动用来控制灯的状态:
代码如下:

static int __init hello_init(void)
{
unsigned long led_addr;

led_addr = (unsigned long)ioremap(0x64000040,0x08);

printk("\nled_addr is 0x%x.\n",led_addr);

writel(0x00,led_addr);

iounmap(led_addr);

printk("\nhelloword:: Hello module is installed!!!!!!\n");

return 0;
}



动态加载的信息如下:
root@seed:/opt# insmod first_driver_hello.ko

led_addr is 0xc4888040.

helloword:: Hello module is installed!!!!!!
root@seed:/opt#

但是灯没有点亮,已证实硬件没有问题,请高手指点~~~
...全文
268 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
zephirus_forever 2011-12-22
  • 打赏
  • 举报
回复
不光是地址的问题,EMIFA没有初始化,CPU不认识该地址,我操作这个是在dsp下,所以没有具体代码
九个太阳2023 2010-10-12
  • 打赏
  • 举报
回复
还是没有搞定,继续努力
九个太阳2023 2010-10-12
  • 打赏
  • 举报
回复
谢谢LS上的这位大哥··
soon 2010-10-07
  • 打赏
  • 举报
回复

这个驱动,请根据你的需要进行修改。
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/input.h>

#include <asm/io.h>



void *R_GPBCON;
void *R_GPBDAT;

static u32 resave_gpbcon;
static u32 resave_gpbdat;

static struct input_dev my_led_dev;


static void iomap_gpb(void)
{
R_GPBCON = ioremap(0x56000010,0x4);
R_GPBDAT = ioremap(0x56000014,0x4);
}

static void unmap_gpb(void)
{
iounmap(R_GPBCON);
iounmap(R_GPBDAT);
}



static void init_led_reg(void)
{
u32 temp;

resave_gpbcon = __raw_readl(R_GPBCON);
resave_gpbdat = __raw_readl(R_GPBDAT);

temp = resave_gpbcon & (~(0xff << 10));
temp |= ((0x1 << 10) | (0x1 << 12)| \
(0x1 << 14) | (0x1 << 16));
__raw_writel(temp,R_GPBCON);


temp = resave_gpbdat | ( 0xf << 5);
__raw_writel(temp,R_GPBDAT);
}


static void resave_led_reg(void)
{
__raw_writel(resave_gpbcon,R_GPBCON);
__raw_writel(resave_gpbdat,R_GPBDAT);
}


static int my_led_event(struct input_dev *dev, \
unsigned int type, unsigned int code, int value)

{
u32 temp;

if (type != EV_LED)
return -1;

switch (code) {
case LED_NUML:
break;
default:
return -1;
}

temp = __raw_readl(R_GPBDAT);
temp &= (~(0xf << 5));

__raw_writel(temp | value,R_GPBDAT);

return 0;
}

static int __init my_led_init(void)
{
init_input_dev(&my_led_dev);

my_led_dev.evbit[0] = BIT(EV_LED);
my_led_dev.ledbit[0] = BIT(LED_NUML);
my_led_dev.event = my_led_event;

my_led_dev.name = "my_led_name";
my_led_dev.phys = "my_led_phys";
my_led_dev.id.bustype = BUS_HOST;
my_led_dev.id.vendor = 0x001f;
my_led_dev.id.product = 0x0001;
my_led_dev.id.version = 0x0100;

iomap_gpb();
init_led_reg();

input_register_device(&my_led_dev);
return 0;
}

static void __exit my_led_exit(void)
{
resave_led_reg();
unmap_gpb();

input_unregister_device(&my_led_dev);
}

module_init(my_led_init);
module_exit(my_led_exit);



下面为测试程序
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <stdio.h>


int main(void)
{
struct input_event my_led_event;
__s32 ret;
__s32 fb;
__u32 loop;
__u32 led_buffer[4] = {0xE,0xD,0xB,0x7};


fb = open("/dev/input/event1",O_RDWR);
if (fb < 0){
printf("open error!\n");
exit(1);
}

my_led_event.type = EV_LED;
my_led_event.code = LED_NUML;


loop = 0;
while (1){
loop &= 0x3;
my_led_event.value = *(led_buffer + loop) << 5;

ret = write(fb,&my_led_event,sizeof(struct input_event));
if (ret < 0){
printf("write error!\n");
exit(1);
}

sleep(1);
loop ++;
}

return 0;
}

laoshizhuce 2010-09-29
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hao507 的回复:]

引用 2 楼 laoshizhuce 的回复:
hao507你好啊

沙发哈

我准备做omap3530的linux 之前是wince

我看你之前也是wince吧

MARK

哈哈,是的啊,之前一直是弄wince的驱动的,但是现在要换linux,还是菜鸟,学习的多着呢,以后多多交流~
[/Quote]

其实我一直觉得linux要比wince有前途

之前也做过一些 ,现在感觉全忘记了

加上现在出来了一个android 更加火了
九个太阳2023 2010-09-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 deep_pro 的回复:]
不要这么直接嘛
先试试读写是否正常
先读 再写 再读,看看你的写入是否有效果
[/Quote]
恩,呵呵,本以为很简单的,我试试
九个太阳2023 2010-09-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 laoshizhuce 的回复:]
hao507你好啊

沙发哈

我准备做omap3530的linux 之前是wince

我看你之前也是wince吧

MARK
[/Quote]
哈哈,是的啊,之前一直是弄wince的驱动的,但是现在要换linux,还是菜鸟,学习的多着呢,以后多多交流~
laoshizhuce 2010-09-29
  • 打赏
  • 举报
回复
hao507你好啊

沙发哈

我准备做omap3530的linux 之前是wince

我看你之前也是wince吧

MARK
deep_pro 2010-09-29
  • 打赏
  • 举报
回复
不要这么直接嘛
先试试读写是否正常
先读 再写 再读,看看你的写入是否有效果
deep_pro 2010-09-29
  • 打赏
  • 举报
回复
随便在内核里找了段代码
if (!request_mem_region(up->port.mapbase, size, "serial")) {
ret = -EBUSY;
break;
}

if (up->port.flags & UPF_IOREMAP) {
up->port.membase = ioremap_nocache(up->port.mapbase,
size);
if (!up->port.membase) {
release_mem_region(up->port.mapbase, size);
ret = -ENOMEM;
}
}

这里你应该先request_mem_region
此外建议使用ioread8 iowrite8 这样的api
九个太阳2023 2010-09-29
  • 打赏
  • 举报
回复
请高手指点··
九个太阳2023 2010-09-29
  • 打赏
  • 举报
回复

static int __init hello_init(void)
{
unsigned long led_addr;
unsigned long value;

led_addr = (unsigned long)ioremap(0x64000040,0x04);
printk("\nled_addr=0x%x.\n",led_addr);

value = readl(led_addr);
printk("\nvalue is 0x%x.\n",value);

writel(0x55,led_addr);

value = readl(led_addr);
printk("\nvalue is 0x%x.\n",value);

writel(0xaa,led_addr);
value = readl(led_addr);
printk("\nvalue is 0x%x.\n",value);

iounmap(led_addr);

printk("\nhelloword:: Hello module is installed!!!!!!\n");

return 0;
}


修改代码如上述

测试的结果是:
root@seed:/opt# insmod first_driver_hello.ko

led_addr is 0xc48d2040.

value is 0x0.

value is 0x0.

value is 0x0.

helloword:: Hello module is installed!!!!!!
root@seed:/opt#

读出来的都是0x00,没有写进去,不知道什么原因导致写不进去数据··

4,436

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧