android qemu-kvm i8254 pit虚拟设备

ubuntu12.04下使用android emulator,启用kvm加速,模拟i8254定时器的代码比较旧,对应于qemu0.14或者之前的版本,这时还没有QOM(qemu object model)模型,虚拟设备的代码是比较简单的。


玩虚拟设备之前,首先得搞明白真实设备怎么玩,有篇文档:http://blog.csdn.net/u013007900/article/details/50408903,看不太明白就再看看计组和哈工大出版的C语言测控,以前上课用的这个。


8254使用的端口时0x40~0x43,共计4个8bit端口,输入时钟频率1193kHZ,使用IRQ0,对应中断向量表中的INT 8。怎么对应,看http://www.360doc.com/content/09/1017/08/128139_7395798.shtmlhttp://blog.csdn.net/duguteng/article/details/7552774

8259主片的IRQ0~7对应INT 8~INT F,从片的IRQ8~IRQ15对应INT 70~INT 77。


有份以前上C语言测控时写的代码,使用了8254的,输入采样周期(in ms)和采样次数,每次采样时打印一个'8'。

注意定时器的最大周期比较短,大约55ms,所以需要使用软件方式扩大定时器的周期,注意周期不是10ms的倍数时的特殊处理。

定时器0工作于模式3,方波发生器。用学硬件的话来说,就是自动重装定时器;用学软件的话来说,就是周期定时器,不是oneshot的。

/* C语言测控程序设计
 * 2012年3月29日
 * 系统XP sp3,编译器:TC3.0,编辑器:VIM7.3
 * */

#include <stdio.h>
#include <dos.h>
#include <graphics.h>
#include <math.h>
#include <string.h>

/*参数*/
float   gfT;                                    //采样周期
long    glN;                                    //采样次数
int     giFlag;                                 //标记时间到
long    glUserCnt;                              //已采样次数
int     giTimerN;                               //采样周期除以10ms
int     giTimerSmallValue;                      //采样周期模10ms后,对应的定时器初值
int     giTimerCnt;                             //定时器中断次数

void    LoadConfig(void);                       //读取配置文件
void    interrupt (*OldIsr08)(void);            //原先的中断函数指针
void    interrupt MyIsr08(void);                //自定义的中断函数
void    TimerInit(void);                        //定时器初始化函数
void    TimerExit(void);                        //定时器恢复函数
void    UserTimerIsr(void);                     //每个采样周期都会调用的函数

int     main()
{
    /*读取配置*/
    LoadConfig();

    /*初始化*/
    TimerInit();

    while((glUserCnt < glN) || (glN == 0))
    {
        if(kbhit())     //特定按键退出
        {
            if(getch() == ' ')
                break;
        }
        if(giFlag)
        {
            giFlag = 0;
            putchar('8');
        }
    }

    /*恢复定时器和dos界面*/
    TimerExit();
    printf("\nthe times of interrupt is: %ld\n",glUserCnt);
    getch();
    return 0;
}

/*定时器中断函数,每到用户设定的时间,调用一次UserTimerIsr()*/
void    interrupt MyIsr08(void)
{
    giTimerCnt++;
    if(giTimerN == 0)   //采样周期小于10ms的情况
    {
        giTimerCnt = 0;
        UserTimerIsr();
        outportb(0x20, 0x20); //清除中断标志位,可以看8259相关的资料
        return;
    }
    if((giTimerSmallValue == 0) && (giTimerCnt == giTimerN))    //采样周期是10ms的倍数的情况
    {
        giTimerCnt = 0;
        UserTimerIsr();
        outportb(0x20, 0x20);
        return;
    }
    if
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值