Board logo

标题: 救命!! uClinux下nios2 如何察看CPU寄存器?还有的中断问题 [打印本页]

作者: 牛牛特工    时间: 2008-4-29 16:23     标题: 救命!! uClinux下nios2 如何察看CPU寄存器?还有的中断问题

请教NIOSII移植uclinux后如何查看寄存器 以及中断问题

交叉编译环境
参考nioswiki上uClinux的移植方法 在ep2c5上移植uClinux已经成功,并DM9000和以太网传输已经正常(都是照着别人的做而已),想做个简单的PIO中断,未果 不知该如何调试 请各位大虾们指导我!!我很郁闷

代码如下(参考的华清远见的linux并且看了linux文件夹下面一些其他的源码)裸奔时中断程序完全正常
头文件 参考了几个文件 把他们包含的头文件都整一起了
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/module.h>
#include <linux/capability.h>
#include <linux/uio.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/version.h>
#include <linux/miscdevice.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/delay.h>
#include "system.h"

#define start0 0xf1//这两个控制字是为了启动外部定时发生中断的电路
#define start1 0x00


//这地方声明了 字符型设备的几个方法 其实这几个函数都没用
//应该起作用的仅仅是模块加载函数
ssize_t SCR_open(struct inode *inode ,struct file *file );
ssize_t SCR_release(struct inode *inode ,struct file *file);
ssize_t SCR_read(struct file *file ,char *buf ,size_t count ,loff_t *fops);
ssize_t SCR_write(struct file *file ,char *buf ,size_t count ,loff_t *fops);
ssize_t SCR_ioctrl(struct inode *inode ,struct file *file,unsigned int cmd ,long data);

struct file_operations SCR_ctrl_ops=
{
open: SCR_open,
read: SCR_read,
write: SCR_write,
ioctl: SCR_ioctrl,
release: SCR_release,
};
static irqreturn_t play(int irq, void* id)
//中断函数 就这么简单咯! 我只要看到零就行了 天啊
{

printk(KERN_ALERT "0");
}
static int __init hello_init(void)
{
int ret = -ENODEV;
volatile unsigned int i,j,k,frame,pos,source;
//注册设备
ret = register_chrdev(241,PIO_1_NAME,&SCR_ctrl_ops);
if(ret < 0)
{
printk("hello module init error %d\n",ret);
}
else
{
printk("hello module init success \n");
}

outw(0xffffffff,PIO_1_BASE+2);//打开PIO1的MASK
outw(0,PIO_1_BASE+3); //清除CAP

ret=request_irq(PIO_1_IRQ,&play,SA_INTERRUPT, "/dev/ctrl","241");
printk("\n-----------------------\nret=%x\n-----------------------\n",ret);
//申请中断

outb(start0,PIO_BASE);
outb(start1,PIO_BASE);//启动外部会定时发生中断的电路

return ret;


}



作者: kzw    时间: 2008-4-29 17:02

像这样调试驱动不方便,基本上不可以,只能你自己确定把中断的驱动注册成功了,终端的响应应该是没有问题的。


作者: 牛牛特工    时间: 2008-4-29 19:22

从request_irq返回值看 返回0中断是注册成功了 后面打印出来了

可它就是进不了中断~中断里面就个printk按道理没错的

[em06]
作者: 牛牛特工    时间: 2008-5-4 10:43

救命啊!!!!
作者: caopengly    时间: 2008-5-4 12:58

如果是中断调试,楼主可以看看下面的“

NIOS II 定时器中断程序跑起来了

关键词NIOS II 定时器中断程序

定时器中断程序也跑起来了(转载)

定时器中断程序也跑起来了,大家分享!

过程如下:

1.首先,硬件方面做以下变动: 在SOPC中添加一个interval timer,命名为timer_0,设置初始化定时周期为500ms,Full featured, 寄存器设置中3个全选,2个输出信号设置都不选,然后finish, 重新Generate,然后到 Quartus 4.2里面去Complation一下,用ASP口烧写到板子的EPCS1里。

2.然后启动NIOS II IDE,写了如下代码(其实都是在我第一个从Hello_led程序中边学边修改过来的)测试程序代码。

#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "altera_avalon_timer_regs.h"
#include "alt_types.h"

volatile alt_u8 count;


static void handle_Timer0_interrupts(void* context, alt_u32 id)
{
alt_u8 a;
volatile alt_u8 *countptr = (volatile alt_u8 *)context;
IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_0_BASE, 0);//清TO标志
a = *countptr; //取出count中的值
a=a<<1; //作移一位
if (a == 0x10) a=1; //我只有4个led,所以要让led循环闪烁
*countptr=a; //重新赋值给count
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, a); //写到LED输出口
}

int main (void)
{

count=1;
alt_irq_register( TIMER_0_IRQ, (void *)&count, handle_Timer0_interrupts); //注册中断函数

//因为我在添加定时器timer_0的时候,设置了初始值为 定时周期500ms的值,我的晶振是50Mhz,
//因为只是简单测试一下定时中断代码的书写方法,所以这里没有重新设置预制值,直接采用初始化时自动
//设置的初始值,当然,也是我懒得去计算初始值,如果要重新设置为不同的定时周期,用下面的2个函数
// IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE, TimerValueLow);
// IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE, TimerValueHigh);
// 其中TimerValueLow和TimerValueHigh是你要设置的低16位和高16位的定时器初值。
//定时器工作时是将这2个寄存器的值调入32位计数器,然后根据CPU的时钟,逐步递减计数器
//的值,直到减到0为止,然后触发中断,并且再次从预制寄存器中将预制值调入32位计数器中,
//再次重复【递减->到0->中断&重新装载初值 】的这个过程
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_0_BASE, 7); //启动timer允许中断,连续计数


while (1) {;}
}






欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0