【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

想学好soc,再怎么看芯片手册和linux kernel都不为过。但是要学习好kernel,那再怎么看skyeye都不为过。学习虚拟机,不光可以自己添加soc,也可以自己添加外设硬件(比如网卡、norflash等等),实在不错。

我们自己可以找一段skyeye的soc代码,看看skyeye是怎么仿真外设的,比如1.2.5版本下对ep9312的仿真,

/*skyeye_mach_ep9312.c - define machine ep9312 for skyeyeCopyright (C) 2003 Skyeye Develop Groupfor help please send mail to <skyeye-developer@lists.sf.linuxforum.net> This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
/** 11/06/2004  clean some codes*       wlm <wlm@student.dlut.edu.cn>* 10/8/2004     init this file.*        add machine ep9312's function. *       Cai Qiang <caiqiang@ustc.edu>        ** */#include "armdefs.h"
#include "clps9312.h"
#include "ep9312.h"
#include "serial_amba.h"
//zzc:2005-1-1
#ifdef __CYGWIN__
//chy 2005-07-28
#include <time.h>
//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
/*struct timeval
{int tv_sec;int tv_usec;
};*/
//AJ2D--------------------------------------------------------------------------
#endif/* 2007-01-18 added by Anthony Lee : for new uart device frame */
#include "skyeye_uart.h"void ep9312_io_write_word (ARMul_State * state, ARMword addr, ARMword data);
ARMword ep9312_io_read_word (ARMul_State * state, ARMword addr);#define NR_UART         3#define UART_FR_TXFE   (1<<7)
#define UART_FR_RXFE    (1<<4)#define UART_IIR_RIS    (1<<1)
#define UART_IIR_TIS    (1<<2)const int TCOI[2] = { 1 << 4, 1 << 5 };
const int UART_RXINTR[3] = { 1 << 23, 1 << 25, 1 << 27 };
const int UART_TXINTR[3] = { 1 << 24, 1 << 26, 1 << 28 };
const int INT_UART[3] = { 1 << (52 - 32), 1 << (54 - 32), 1 << (55 - 32) };
const int iConsole = 0;        //index of uart of serial console/*Internal IO Register*/
typedef struct ep9312_io
{ARMword syscon_devcfg; /* System control */ARMword intsr[2];   /* Interrupt status reg */ARMword intmr[2]; /* Interrupt mask reg */struct ep9312_tc_io tc[4];struct ep9312_uart_io uart[NR_UART];} ep9312_io_t;static ep9312_io_t ep9312_io;
#define io ep9312_iostatic void
ep9312_update_int (ARMul_State * state)
{ARMword requests = io.intsr[0] & io.intmr[0];requests |= io.intsr[1] & io.intmr[1];state->NfiqSig = (requests & 0x0001) ? LOW : HIGH;state->NirqSig = (requests & 0xfffe) ? LOW : HIGH;
}static void
ep9312_io_reset (ARMul_State * state)
{int i;io.syscon_devcfg = 0;io.intmr[0] = 0;io.intmr[1] = 0;/* reset TC register */io.tc[0].value = 0;io.tc[1].value = 0;io.tc[2].value = 0;io.tc[0].mod_value = 0xffff;io.tc[1].mod_value = 0xffff;io.tc[2].mod_value = 0xffffffff;for (i = 0; i < NR_UART; i++) {io.uart[i].dr = 0;io.uart[i].fr = UART_FR_TXFE;}
}void
ep9312_io_do_cycle (ARMul_State * state)
{int i;/* We must implement TC1, TC2 and TC4 */for (i = 0; i < 2; i++) {if (io.tc[i].value == 0) {if (io.tc[i].ctl & TC_CTL_MODE)io.tc[i].value = io.tc[i].load;elseio.tc[i].value = io.tc[i].mod_value;io.intsr[0] |= TCOI[i];ep9312_update_int (state);}else {io.tc[i].value--;}}io.tc[3].load++;if (!(io.intsr[0] & (UART_RXINTR[iConsole]))&& io.uart[iConsole].dr == 0) {/* 2007-01-18 modified by Anthony Lee : for new uart device frame */struct timeval tv;unsigned char buf;tv.tv_sec = 0;tv.tv_usec = 0;if(skyeye_uart_read(-1, &buf, 1, &tv, NULL) > 0){io.uart[iConsole].dr = (int) buf;io.intsr[0] |= UART_RXINTR[iConsole];io.intmr[0] |= UART_RXINTR[iConsole];io.intsr[1] |= INT_UART[iConsole];io.intmr[1] |= INT_UART[iConsole];io.uart[iConsole].iir |= UART_IIR_RIS;io.uart[iConsole].fr &= ~UART_FR_RXFE;ep9312_update_int (state);}}          //if (!(io.intsr & URXINT))
}static void
ep9312_uart_read (ARMul_State * state, u32 offset, u32 * data, int index)
{switch (offset) {case UART_DR:*data = io.uart[index].dr;io.uart[index].dr = 0;io.intsr[0] &= ~(UART_RXINTR[index]);io.intsr[1] &= ~(INT_UART[index]);io.uart[index].iir &= ~UART_IIR_RIS;io.uart[index].fr |= UART_FR_RXFE;ep9312_update_int (state);break;case UART_RSR:*data = io.uart[index].rsr;break;//case UART_ECR:case UART_CR_H:case UART_CR_M:case UART_CR_L:break;case UART_CR:*data = io.uart[index].cr;break;case UART_FR:*data = io.uart[index].fr;break;case UART_IIR:*data = io.uart[index].iir;break;//case UART_ICR:case UART_ILPR:case UART_DMACR:case UART_TCR:case UART_TISR:case UART_TOCR:case UART_TMR:case UART_MCR:case UART_MSR:break;default:SKYEYE_DBG ("%s(0x%x, 0x%x)\n", __func__, offset, data);break;}
}
static void
ep9312_uart_write (ARMul_State * state, u32 offset, u32 data, int index)
{switch (offset) {case UART_DR:{char c = data;/* 2007-01-18 modified by Anthony Lee : for new uart device frame */skyeye_uart_write(-1, &c, 1, NULL);}case UART_RSR://case UART_ECR:case UART_CR_H:case UART_CR_M:case UART_CR_L:break;case UART_CR:{io.uart[index].cr = data;if ((data & AMBA_UARTCR_TIE) == 0) {io.intmr[0] &= ~(UART_TXINTR[index]);io.intsr[0] &= ~(UART_TXINTR[index]);io.intsr[1] &= ~(INT_UART[index]);io.intmr[1] &= ~(INT_UART[index]);io.uart[index].iir &= ~(UART_IIR_TIS); //Interrupt Identification and Clear}else {io.intmr[0] |= (UART_TXINTR[index]);io.intsr[0] |= (UART_TXINTR[index]);io.intsr[1] = (INT_UART[index]);io.intmr[1] = (INT_UART[index]);io.uart[index].iir |= (UART_IIR_TIS);}ep9312_update_int (state);}break;case UART_FR:case UART_IIR:io.uart[index].iir = data;break;//case UART_ICR:case UART_ILPR:case UART_DMACR:case UART_TCR:case UART_TISR:case UART_TOCR:case UART_TMR:case UART_MCR:case UART_MSR:break;default:SKYEYE_DBG ("%s(0x%x, 0x%x)\n", __func__, offset, data);}
}/* Timer read/write register */
static void
ep9312_tc_read (u32 offset, u32 * data, int index)
{if (index == 4) {if (offset == TC_VALUELOW)*data = io.tc[index].load;else if (offset == TC_VALUEHIGH)*data = io.tc[index].value;}switch (offset) {case TC_LOAD:*data = io.tc[index].load;break;case TC_VALUE:*data = io.tc[index].value;break;case TC_CTL:*data = io.tc[index].ctl;break;case TC_CLEAR:SKYEYE_DBG ("%s(0x%x, 0x%x): read WO register\n", __func__,offset, data);break;default:SKYEYE_DBG ("%s(0x%x, 0x%x)\n", __func__, offset, data);break;}
}
static void
ep9312_tc_write (ARMul_State * state, u32 offset, u32 data, int index)
{switch (offset) {case TC_LOAD:io.tc[index].load = data;break;case TC_VALUE:SKYEYE_DBG ("%s(0x%x, 0x%x): write RO register\n", __func__,offset, data);break;case TC_CTL:io.tc[index].ctl = data;break;case TC_CLEAR:io.intsr[0] &= ~TCOI[index];ep9312_update_int (state);break;default:SKYEYE_DBG ("%s(0x%x, 0x%x)\n", __func__, offset, data);break;}
}ARMword
ep9312_io_read_byte (ARMul_State * state, ARMword addr)
{return ep9312_io_read_word (state, addr);
}ARMword
ep9312_io_read_halfword (ARMul_State * state, ARMword addr)
{SKYEYE_DBG ("SKYEYE: %s error\n", __func__);
}ARMword
ep9312_io_read_word (ARMul_State * state, ARMword addr)
{ARMword data = 0;/* TC1 */if ((addr >= EP9312_TC_BASE1) &&(addr < (EP9312_TC_BASE1 + EP9312_TC_SIZE))) {ep9312_tc_read ((u32) (addr - EP9312_TC_BASE1),(u32 *) & data, 0);}/* TC2 */if ((addr >= EP9312_TC_BASE4) &&(addr < (EP9312_TC_BASE4 + EP9312_TC_SIZE))) {ep9312_tc_read ((u32) (addr - EP9312_TC_BASE4),(u32 *) & data, 3);}/* UART1 */if ((addr >= EP9312_UART_BASE1) &&(addr < (EP9312_UART_BASE1 + EP9312_UART_SIZE))) {ep9312_uart_read (state, (u32) (addr - EP9312_UART_BASE1),(u32 *) & data, 0);return data;}/* UART3 */if ((addr >= EP9312_UART_BASE3) &&(addr < (EP9312_UART_BASE3 + EP9312_UART_SIZE))) {ep9312_uart_read (state, (u32) (addr - EP9312_UART_BASE3),(u32 *) & data, 2);return data;}switch (addr) {case SYSCON_PWRCNT:break;case VIC0INTENABLE:data = io.intmr[0];
//              printf("%s(0x%08x) = 0x%08x\n", __func__, addr, data);break;case VIC0IRQSTATUS:data = io.intsr[0];io.intsr[0] = 0; //!!!break;case VIC1IRQSTATUS:data = io.intsr[1];io.intsr[1] = 0;break;case RTCDR:case AACGCR:case AACRGIS:
//              printf("%s(0x%08x) = 0x%08x\n", __func__, addr, data);break;case SYSCON_DEVCFG:data = io.syscon_devcfg;break;default:SKYEYE_DBG ("SKYEYE:unknown io addr, %s(0x%08x) = 0x%08x\n",__func__, addr, data);break;}return data;
}void
ep9312_io_write_byte (ARMul_State * state, ARMword addr, ARMword data)
{ep9312_io_write_word (state, addr, data);
}void
ep9312_io_write_halfword (ARMul_State * state, ARMword addr, ARMword data)
{SKYEYE_DBG ("SKYEYE: %s error\n", __func__);
}void
ep9312_io_write_word (ARMul_State * state, ARMword addr, ARMword data)
{ARMword tmp;if ((addr >= EP9312_TC_BASE1) &&(addr < (EP9312_TC_BASE1 + EP9312_TC_SIZE))) {ep9312_tc_write (state, (u32) (addr - EP9312_TC_BASE1), data,0);}if ((addr >= EP9312_UART_BASE1) &&(addr < (EP9312_UART_BASE1 + EP9312_UART_SIZE))) {ep9312_uart_write (state, (u32) (addr - EP9312_UART_BASE1),data, 0);}if ((addr >= EP9312_UART_BASE3) &&(addr < (EP9312_UART_BASE3 + EP9312_UART_SIZE))) {ep9312_uart_write (state, (u32) (addr - EP9312_UART_BASE3),data, 2);}switch (addr) {case SYSCON_CLKSET1:break;case SYSCON_CLKSET2:case SYSCON_PWRCNT:break;case VIC0INTENABLE:io.intmr[0] = data;if (data != 0x10 && data != 0x20)printf ("SKYEYE: write VIC0INTENABLE=0x%x\n", data);ep9312_update_int (state);break;case VIC1INTENABLE:io.intmr[1] = data;
//              printf("SKYEYE: write VIC1INTENABLE=0x%x\n", data);ep9312_update_int (state);break;case VIC0INTENCLEAR:io.intmr[0] ^= data;ep9312_update_int (state);break;case VIC1INTENCLEAR:io.intmr[1] ^= data;ep9312_update_int (state);break;case SYSCON_DEVCFG:io.syscon_devcfg = data;break;default:SKYEYE_DBG("SKYEYE:unknown io addr, %s(0x%08x, 0x%08x), pc %x \n",__func__, addr, data, state->Reg[15]);break;}
}void
ep9312_mach_init (ARMul_State * state, machine_config_t * this_mach)
{ARMul_SelectProcessor (state, ARM_v4_Prop);/* ARM920T uses LOW */state->lateabtSig = LOW;//      state->Reg[1] = 282;    //for EP9312 2.4.x arch idstate->Reg[1] = 451;    //for EP9312 2.6.x arch id//state->Reg[1] = 386;  //for EP9315 2.4.x arch idthis_mach->mach_io_do_cycle = ep9312_io_do_cycle;this_mach->mach_io_reset = ep9312_io_reset;this_mach->mach_io_read_byte = ep9312_io_read_byte;this_mach->mach_io_write_byte = ep9312_io_write_byte;this_mach->mach_io_read_halfword = ep9312_io_read_halfword;this_mach->mach_io_write_halfword = ep9312_io_write_halfword;this_mach->mach_io_read_word = ep9312_io_read_word;this_mach->mach_io_write_word = ep9312_io_write_word;this_mach->mach_update_int = ep9312_update_int;}

我觉得soc仿真的意义在于让外设的地址读写变得有意义,比如如何让串口地址进行输出、让时钟进行计数、让中断可以真正地发挥作用。上面这段代码看上去行数很多,但是最重要的还是最后一个函数。当然,除此之外,系统注册也是必不可少的,

machine_config_t arm_machines[] = {/* machine define for cpu without mmu */{"at91", at91_mach_init, NULL, NULL, NULL},        /* ATMEL AT91X40 */{"lpc", lpc_mach_init, NULL, NULL, NULL},      /* PHILIPS LPC2xxxx */{"s3c4510b", s3c4510b_mach_init, NULL, NULL, NULL}, /* Samsung s3c4510b */{"s3c44b0x", s3c44b0x_mach_init, NULL, NULL, NULL}, /* Samsung s3c44b0x */{"s3c44b0", s3c44b0x_mach_init, NULL, NULL, NULL},  /* Samsung s3c44b0x */{"s3c3410x", s3c3410x_mach_init, NULL, NULL, NULL}, /* Samsung s3c3410x *//* machine define for cpu with mmu */{"ep7312", ep7312_mach_init, NULL, NULL, NULL},        /* Cirrus Logic EP7312 */{"lh79520", lh79520_mach_init, NULL, NULL, NULL},    /* sharp LH79520 */{"ep9312", ep9312_mach_init, NULL, NULL, NULL},        /* Cirrus Logic EP9312 */{"cs89712", cs89712_mach_init, NULL, NULL, NULL},    /* cs89712 */{"sa1100", sa1100_mach_init, NULL, NULL, NULL},      /* sa1100 */{"pxa_lubbock", pxa250_mach_init, NULL, NULL, NULL},  /* xscale pxa250 lubbock developboard */{"pxa_mainstone", pxa270_mach_init, NULL, NULL, NULL},    /* xscale pxa270 mainstone developboard */{"at91rm92", at91rm92_mach_init, NULL, NULL, NULL}, /* at91RM9200 */{"s3c2410x", s3c2410x_mach_init, NULL, NULL, NULL},   /* s3c2410x */{"s3c2440", s3c2440_mach_init, NULL, NULL, NULL},   /* s3c2440 */{"sharp_lh7a400", shp_mach_init, NULL, NULL, NULL},  /* sharp lh7a400 developboard */{"ns9750", ns9750_mach_init, NULL, NULL, NULL},       /* NetSilicon ns9750 */{"lpc2210", lpc2210_mach_init, NULL, NULL, NULL},  /* Philips LPC2210 */{"ps7500", ps7500_mach_init, NULL, NULL, NULL},      /* Cirrus Logic PS7500FE */
};

有了这两个文件,基本上soc的逻辑算是了解了。

随想录(skyeye中的soc仿真)相关推荐

  1. FMI在仿真软件SkyEye中的应用

    1.仿真技术的困境 随着科技的发展,我国在安全攸关领域对于嵌入式软件的应用日益广泛,并且对于软硬件的性能及可靠性等方面要求变得更高.面对各种复杂的系统设计所提供的设计和分析手段也逐渐完善,其中仿真技术 ...

  2. 膨胀的计算机仿真,制冷空调中的计算机仿真与控制

    <制冷空调中的计算机仿真与控制>由会员分享,可在线阅读,更多相关<制冷空调中的计算机仿真与控制(145页珍藏版)>请在人人文库网上搜索. 1.第5章 制冷空调中的计算机仿真与控 ...

  3. 无功功率控制模式matlab,第9章_MATLAB在风力发电技术中的应用仿真.ppt

    图9-21 电网故障时电压控制模式下风电机组输出特性变化曲线 图9-22 电网故障时无功功率控制模式下风电机组输出特性变化曲线 第9章 MATLAB在风力发电技术中的应用仿真 9.1 定速风电机组的仿 ...

  4. 电力电子技术 matlab仿真指导,在_电力电子技术_课程教学中展开Matlab仿真训练_唐贤伦...

    教 学改革广角 中国电力教育 2009年10月上 总第146期 "电力电子技术"是电气工程及其自动化等专业的重要专业 基础课,也是实用性.工程性和综合性很强的课程.作为自动化.电气 ...

  5. 工艺仿真软件_中科院科研项目:算法与软件工程集成电路制造中的工艺仿真

    本文来自微信公众号--青人留学. 中科院科研项目:算法与软件工程集成电路制造中的工艺仿真​mp.weixin.qq.com 项目简介 集成电路制造过程是由一系列的工艺单元组成的,如:光刻.刻蚀.薄膜沉 ...

  6. 基于Unity3d的虚拟装配中的机械运动仿真

    基于Unity3d的虚拟装配中的机械运动仿真 前言 1.创建缸体相关的物体和对象 2.鼠标随意拖动和旋转物体的脚本 3.利用标记点进行虚拟装配 4.缸体的旋转 前言 在研究基于unity3d的虚拟装配 ...

  7. 无迹卡尔曼滤波UKF—目标跟踪中的应用(仿真部分)

    无迹卡尔曼滤波UKF-目标跟踪中的应用(仿真部分) 原创不易,路过的各位大佬请点个赞 机动目标跟踪/非线性滤波/传感器融合/导航等探讨联系WX: ZB823618313 算法部分见博客: [无迹卡尔曼 ...

  8. MATLAB轨迹规划 发给ROS中机器人实现仿真运动

    MATLAB轨迹规划 发给ROS中机器人实现仿真运动 现象如图所示: 0.matlab 与 ROS 通信: https://blog.csdn.net/qq_40569926/article/deta ...

  9. BMS算法中定义SOC需考虑哪些因素

    SOC(state of charge)算法一直是BMS开发应用的关键技术之一.因此讨论SOC算法的技术文章很常见,企业对SOC估算的高精度也往往是宣传的亮点.而关于SOC详尽的解释和定义却不常被考虑 ...

最新文章

  1. Smali文件添加try/catch语句,出现“invalid use of move-exception”异常
  2. 【废弃】【WIP】JavaScript 函数
  3. adobe仿宋std r常规_宜春MF4003-5-06-CV-R气体质量流量计
  4. php修改文件上传大小限制
  5. int、bigint、mediumint、smallint、tinyint的比较
  6. SAP Cloud for Customer的前端框架是如何基于SAP UI5框架开发的
  7. php如何获得文件数量,PHP:获取目录中文件数量的最有效方法
  8. Windows 10系统安装JDK1.8与配置环境
  9. 掌握Python爬虫基础,仅需1小时!
  10. cognito_将Spring Boot应用程序与Amazon Cognito集成
  11. 控制台输入一个整数,取该整数的各位数,判断其是否能被该整数整除,能则返回true,不能则返回false
  12. 【资源分享】ArcFace Demo [Android]
  13. linux之--install超时
  14. Html源码在线翻译,HTML – 谷歌翻译网站
  15. R语言实现随机分组(按照学号或者是姓名随机分组)
  16. 正则表达式 正则表达式语法
  17. 操作系统信号量问题-------南北桥问题java实现
  18. 广东省计算机设计大赛文档,广东省大学生计算机设计大赛.doc
  19. 反向代理和正向代理的概念
  20. iOS: 仿新浪微博 OC (持续更新ing)

热门文章

  1. Oracle 11gR2 RAC 安装Grid Infrastructure错误
  2. 扩展JS格式化(Format)功能及评论树
  3. Do 32-bit build only with XCode 5.1
  4. 使用JAVASCRIPT进行全屏显示页面,就像触摸屏显示效果
  5. Linux rmmod命令
  6. Re-Order Buffer
  7. [C++]各编译器对C++11的支持比较
  8. Microsoft Office 企业记分卡管理服务器
  9. 软考信息系统项目管理师_信息系统项目管理基础---软考高级之信息系统项目管理师008
  10. 大数据之-Hadoop3.x_MapReduce_WordCount案例需求分析---大数据之hadoop3.x工作笔记0087