虚拟平台嵌入式系统开源项目包括eCos RTEMS OKL4
1. 嵌入式实验室的创建本人是一个嵌入式系统的爱好者,移植和应用过多种嵌入式系统。工作以来主要从事WinCE,Linux和Android的开发。
一直有一个梦想,希望像我一样的嵌入式系统爱好和工作者,能够在没有硬件的条件下去了解和开发这样的系统。
现在,自由的操作系统层出不穷,对移植和开发的文档却依然晦涩难懂。我希望我们能在这样的虚拟的平台上(比如我现在专注的
mini2440 QEMU)把我们的每一次移植都能够图文并茂的通过docbook 记录在案,这将能更大的提升自由软件文档的阅读效果。
我们不专注于系统本身,但是我们专注于这样的虚拟应用。我们会不遗余力的把我们的文档和代码贡献给任何人。
当然也会提供给我们移植的操作系统的组织。在这样的环境中,我希望大家和我能继续共同成长。
虽然我已经过了而立之年,但是我感觉我依旧浑身充满了力量。
我建立的自由软件项目,名称是eMBosLab, 在未来的日子里,我将把我仅剩的力量投入进来。
让更多的人能够通过这样一个平台,学习甚至研究嵌入式系统,更轻松的投入到工作中。
我还会和朋友一起通过docbook的方式,记录我们的每一次成长历程。
项目主页:
https://sourceforge.net/projects/emboslab/
代码管理方式:
大部分代码采用GIT来管理
http://emboslab.git.sourceforge.net/git/gitweb-index.cgi
一些操作系统如果用hg,或者svn,我们会延续他
http://emboslab.hg.sourceforge.net/hgweb/emboslab
2. eMBosLab RTEMS:(具体细节请参考雪松的blog)
http://blog.csdn.net/coolbacon
更新内容:
RTEMS 增加DM9000网卡支持查询和中断方式,网络程序测试OK
RTEMS 修正PLL bug, ticker 运行正常
RTEMS for emboslab 增加mini2440 qemu BSP
下载方法
git clone git://emboslab.git.sourceforge.net/gitroot/emboslab/rtems-4.9.5-emboslab
http://hi.csdn.net/attachment/201103/25/4215402_13010628454yy5.png
3. eMBosLab eCos:更新内容:
20110328 23:00
通过ecosconfig add net_drivers自动增加网卡驱动的QEMU依赖关系。
20110321 18:00
增加MINI2440 BSP源代码,包括FLASH驱动,DM9000网卡驱动极其LCD支持
20110321 10:00
eCos for emboslab 合并了yaffs和nand 模块
下载方法
hg clone hg://emboslab.hg.sourceforge.net/hgweb/emboslab/ecos-emboslab
4.eMBosLab Docs:更新内容:
20110328 23:00
docbook模板已经建好,后续的部分文档会采用英文配合图形的方式。
20110322 12:00
从ecos中的文档中,剥离出相对简单的docbook应用架构作为后续文档编写的体系结构。
可以直接生成html和pdf A4页面的文档
下载方法:
git clone git://emboslab.git.sourceforge.net/gitroot/emboslab/docbook-emboslab
5.网站介绍
这是主页,为了能用git和hg, 我选择了sourceforge平台
https://sourceforge.net/projects/emboslab/
http://hi.csdn.net/attachment/201103/19/4215402_13005070172wE3.png
这是所有的源代码:
目前已经把RTEMS for QEMU MINI2440放在了上面,希望能有更多的人参与。
这将是一个自由的技术学习和交流平台。
source code address
http://emboslab.git.sourceforge.net/git/gitweb-index.cgi
http://hi.csdn.net/attachment/201103/19/4215402_1300506947eMzC.png
网页上也能看到我在RTEMS做的所有工作。
http://hi.csdn.net/attachment/201103/19/4215402_13005071159598.png
[ 本帖最后由 rickleaf 于 2011-4-11 09:01 编辑 ]
ecos在mini2440 qemu的网络功能测试
终于可以方便的用mini2440 qemu的网络功能了,大家参考一下雪松的这篇帖子
http://blog.csdn.net/coolbacon/archive/2011/03/16/6252938.aspx
既然可以这样用了,我重新整理了mini2440的redboot
1. 根据qemu对dm9000模拟的限制,对dm9000驱动程序做了新的修改
http://hi.csdn.net/attachment/201103/16/4215402_1300283210N70h.png
2. ecos的看家绝技,gdb调试应用程序
根据雪松的修改,现在可以用arm-eabi-gdb 的target remote来做ecos 应用程序的单步调试了http://hi.csdn.net/attachment/201103/16/4215402_13002848283iIt.png
3. ecos的httpd 在mini2440 qemu的测试
http://hi.csdn.net/attachment/201103/16/4215402_1300286583y3oA.png
http://hi.csdn.net/attachment/201103/16/4215402_1300286604Qjr6.png
[ 本帖最后由 rickleaf 于 2011-4-11 08:57 编辑 ]
Microwindows 及触摸屏实现
1. 修复MINI2440 QEMU的BUG开始的我用ecos里面仅有的两个ARM下面的touch 驱动来做一个中断测试,都快疯了,没有任何反应。
后来看到RT-Thread的例子可以正常运行,于是才想看看他们呢对MINI2440 QEMU的修改。
真的要感谢所有自由组织的无私奉献。
果然,MINI2440的QEMU采用的是S3C2410的TOUCH接口,里面关于PenDown和PenUP的寄存器位都木有。
代码已经上传到了emboslab git 库中qemu-mini2440的ecos-emboslab 分支,这里还是简要介绍一下。
--------------------------------- hw/s3c2410.c ---------------------------------
index d1e4c92..bdf8a73 100644
@@ -1630,6 +1630,14 @@ static void s3c_adc_tick(void *opaque)
qemu_mod_timer(s->tst, qemu_get_clock(vm_clock) +
(ticks_per_sec >> 5));
}
/*
这个是QEMU实现ARM中断方式的机制
可以这样理解:如果对QEMU的窗口做Penup的时候,触发一个专断给CPU。
*/
+ else
+ {
+ if (((s->ts & 3) == 3) && (s->ts & (1<<8)) && (s->enable))
+ qemu_irq_raise(s->tcirq);
+
+
qemu_mod_timer(s->tst, qemu_get_clock(vm_clock) +
+ (ticks_per_sec >> 5));
+ }
}
static void s3c_adc_event(void *opaque,
@@ -1689,7 +1697,7 @@ static void s3c_adc_write(void *opaque, target_phys_addr_t addr,
break;
case S3C_ADCTSC:
- s->ts = value & 0xff;
+ s->ts = value & 0x1ff; /*增加了Pendown和Penup的控制位*/
break;
case S3C_ADCDLY:
2. 实现触摸屏驱动(尚有BUG)目前官方的触屏驱动有两个,我们看下
ricky@ricky-laptop:ecos-emboslab$ cd packages/devs/touch/arm/
ricky@ricky-laptop:arm$ ls
aaed2000ipaq
如果让Microwindows支持Touch只要实现这样的一个标准的Touch驱动就可以了。
在Microwindows的部分调用这个标准的ecos字符形设备就可以了。
不过从代码看来,ecos并没有对Touch驱动有严格的API定义,所以在网上你能看到很多种实现方法。
既然Microwindows用了字符形的设备,那么我们也就按照这个架构实现一下吧。
我们先看一下ecos的字符形设备是什么样子的,具体的请看ecos的参考手册(如何生成最新的参考手册,我会在另一篇博客中讲述)
CHAR_DEVIO_TABLE(mini2440_ts_handlers,
NULL, // Unsupported write() function
ts_read,
ts_select,
ts_get_config,
ts_set_config);
CHAR_DEVTAB_ENTRY(mini2440_ts_device,
CYGDAT_DEVS_TOUCH_MINI2440_NAME, /*这个是字符形设备的描述符,在CDL文件中定义"/dev/ts",和Linux的驱动文件很相似 */
NULL, // Base device name
&mini2440_ts_handlers,
ts_init,
ts_lookup,/*重点看这个函数:当设备被open的时候这个callback函数会被调用*/
NULL); // Private data pointer
关于如何实现更好的touch架构,本人还在研究。
现在的方案是
在设备初始化的时候配置硬件资源和终端设置,
在设备被打开,也就是ts_lookup里面创建中断响应函数,把转化好的touch 数据放到队列中等待上层(Microwindows)
来读取。
看下初始化部分
static bool
ts_init(struct cyg_devtab_entry *tab)
{
cyg_uint32 _dummy;
HAL_WRITE_UINT32(ADCCON,S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(9));
HAL_WRITE_UINT32(ADCDLY,50000);
HAL_WRITE_UINT32(ADCTSC,WAIT4INT(0));/*这里就是使能,PenDownUP终端*/
//HAL_WRITE_UINT32(INTMSK, BIT_ALLMSK);
HAL_READ_UINT32(SUBSRCPND, _dummy);
_dummy |= BIT_SUB_TC;
_dummy |= BIT_SUB_ADC;
HAL_WRITE_UINT32(SUBSRCPND, _dummy);
cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_ADC);
cyg_selinit(&ts_select_info);
/* install interrupt handler */
HAL_READ_UINT32(INTSUBMSK, _dummy);
_dummy &= ~BIT_SUB_ADC;
_dummy &= ~BIT_SUB_TC;
HAL_WRITE_UINT32(INTSUBMSK, _dummy);
HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_ADC);
return true;
}
/*设备打开函数,创建了ADC中断的挂钩函数cyg_mini2440_ts_isr和cyg_mini2440_ts_dsr*/
if (!_is_open) {
_is_open = true;
cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_ADC,
0,
(CYG_ADDRWORD)0,
cyg_mini2440_ts_isr,
cyg_mini2440_ts_dsr,
&ts_thread_handle,
&ts_thread_data);
cyg_drv_interrupt_attach(ts_thread_handle);
cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_ADC);
}
return ENOERR;
}
罗嗦两句,ecos在创建的时候就参考了很多linux的风格,比如我们看到上面的isr和dsr很像Linux对中断处理的上半和下半。
具体的实现机理本人也在研究呢,目前位置我只是知道如何应用。
isr中希望用户能快速的响应终端,在isr结束的时候往往有下面的代码
cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_ADC);
上面的这行主要是在函数返回前开启这个中断
return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
后面这个有两个含义,第一个是告诉系统这个中断我已经知道了,做了我应该做的事情。第二个含义就是红色的部分会在函数返回之后
出发这个终端的DSR处理程序。
那么这个touch驱动到底需要还是不需要DSR呢,本人下不了结论。
本人是做Linux的,知道Linux一般的input driver一般用到后半的多是处理report机制,
为了不把问题复杂化,我们现让硬件能动起来,欢迎其他人给我建议
2440的Touch中断处理暂时比较简单
if (res& (1 << 10))/*ADC的采用的后要继续出发PenDownUP中断*/
{
//diag_printf("ADC Interrupt\n");
HAL_READ_UINT32(SUBSRCPND, reg);
reg |= BIT_SUB_ADC;
HAL_WRITE_UINT32(SUBSRCPND, reg);
x = read_ts_x();
y = read_ts_y();
lastX = x;lastY = y;
//diag_printf("X = %x, Y = %x\n", x, y);
HAL_WRITE_UINT32(ADCTSC,WAIT4INT(1));
}
if (res& (1 << 9)){ /*PenDownUp中断记录Touch的按下和抬起,同时出发ADC的采样*/
//diag_printf("TS Interrupt\n");
HAL_READ_UINT32(SUBSRCPND, reg);
reg |= BIT_SUB_TC;
HAL_WRITE_UINT32(SUBSRCPND, reg);
HAL_READ_UINT32(ADCDAT0, data0);
HAL_READ_UINT32(ADCDAT1, data1);
updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
if(updown)
{
x = read_ts_x();
y = read_ts_y();
//diag_printf("X = %x, Y = %x\n", x, y);
//diag_printf("pen_down#######################################################################\n");
if ((x < X_THRESHOLD) || (y < Y_THRESHOLD)) {
// Ignore 'bad' samples
}
lastX = x;lastY = y;
HAL_WRITE_UINT32(ADCTSC, S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST);
HAL_READ_UINT32(ADCCON, reg);
reg |= S3C2410_ADCCON_ENABLE_START;
HAL_WRITE_UINT32(ADCCON, reg);
pen_down = true;
}
else
{
x = lastX;
y = lastY;
HAL_WRITE_UINT32(ADCTSC,WAIT4INT(0));
pen_down = false;
//diag_printf("pen_up#######################################################################\n");
}
}
/*把合理的数据处理后放入一个events数组中,等待上层来读取*/
if (num_events < MAX_EVENTS) {
num_events++;
ev = &_events;
if (_event_put == MAX_EVENTS) {
_event_put = 0;
}
ev->button_state = pen_down ? 0x04 : 0x00;
ev->xPos = x;
ev->yPos = y;
if (ts_select_active) {
ts_select_active = false;
cyg_selwakeup(&ts_select_info);
}
}
续Microwindow和触屏
3. 修正eCos自带Microwindows的ecos_app错误目前发现的一个问题是,ecos之前曾经采纳了一个牛的patch,他应用HAL_TABLE实现了基于Microwindows的APP定义方式。很巧妙,那么什么是HAL_TABLE呢,我们可以理解为为了实现更好的表的管理的一种机制,可以把我们要存放的表通过宏
放到内存中的某个位置,大家可以在google上找一下,ecos在这个部分应用还是比较有特点的。
尤其是在二维表的处理上有很多特别的应用,redboot的一些命令就是例子
ecos_mw_app.h
typedef void fun(CYG_ADDRWORD);
typedef struct _mw_app_entry {
char *name;
fun *entry;
int prio;
fun *init;
cyg_handle_t t;
cyg_thread t_obj;
char stack;
} CYG_HAL_TABLE_TYPE _mw_app_entry_t;
#define _mw_app(_name_,_id_,_pri_,_init_) \
externC void _id_##_thread(CYG_ADDRWORD data); \
_mw_app_entry_t _mw_app_##_pri_##_##_id_ \
CYG_HAL_TABLE_QUALIFIED_ENTRY(_mw_apps,_pri_) = \
{ _name_, _id_##_thread, _pri_, _init_};
#define ECOS_MW_STARTUP_PRIORITY 11
#define ECOS_MW_NANOX_PRIORITY (ECOS_MW_STARTUP_PRIORITY+1)
#define ECOS_MW_KND_PRIORITY (ECOS_MW_STARTUP_PRIORITY+2)
#define ECOS_MW_NANOWM_PRIORITY(ECOS_MW_STARTUP_PRIORITY+4)
#define ECOS_MW_APP_PRIORITY (ECOS_MW_STARTUP_PRIORITY+5)
ecos_app.c
CYG_HAL_TABLE_BEGIN( __MW_APP_TAB__, _mw_apps );
CYG_HAL_TABLE_END( __MW_APP_TAB_END__, _mw_apps );
extern struct _mw_app_entry __MW_APP_TAB__[], __MW_APP_TAB_END__;
为什么提到这个呢,到目前位置我不能十分的确定是这个机制有问题还是QEMU本身对于内存管理的问题。
如果我在Microwindows访问我的设备文件,就是open我们之前创建的/dev/ts这个时候貌似用HAL_TABLE存放的UI线程信息就读不到了。
如果可以打message,可以看到不能创建我们要的Microwindows的一些线程,当然也就不能看到画面了。
比较简单的做法就是参考ecos之前的代码,或者干脆去看官方Microwindows的代码,用一个数组去存放线程信息。
struct nx_thread _threads[] = {
{ "System startup", startup_thread, 11 },
{ "Nano-X server",nanox_thread, 12 },
{ "Nano-WM", nanowm_thread, 14 },
/*{ "Nano-KBD", nxkbd_thread, 13 },*/
#ifdef USE_NXSCRIBBLE
{ "Scribble", nxscribble_thread, 20 },
#endif
#ifdef USE_LANDMINE
{ "Landmine", landmine_thread, 19 },
#endif
#ifdef USE_NTETRIS
{ "Nano-Tetris", ntetris_thread, 18 },
#endif
#ifdef USE_WORLD
{ "World Map", world_thread, 21 },
#endif
{ "demo", demo_thread, 22 },
};
接下来你就看到Microwindows了,进入下一个环节。
4. Show 图咯
http://hi.csdn.net/attachment/201104/1/4215402_1301670149X3Vi.png
RTEMS网卡驱动移植
我把雪松的帖子也转过来。鼓励大家看他的原帖子,他是这个专家。
http://blog.csdn.net/coolbacon/archive/2011/03/22/6269551.aspx
这两天抽了个空,在rickleaf移植的 qemu mini2440 的rtems 4.9.5 bsp 上做了一些修改:
1.原来mini2440的 bsp是基于 gp32的bsp修改,复用了部分的gp32代码。cpu类型实际上使用的是s3c2410。这不利于对mini2440的修改。所以,增加了新cpu型号s3c2440,并将mini2440修改成独立的bsp。
如果有朋友在bootstrap -p 和 bootstrap 时,嫌生成configure 的时间太长,建议将libbsp下和libcpu下不使用的bsp和cpu型号删除。以增加开发效率。
2.s3c2410 cpu的PLL部分和s3c2440的 PLL 还是有些许差别,造成rtems的tick不准,已经修改。
3.支持dm9000的网络。
代码请安装版本管理工具 git,使用命令:
git clone git://emboslab.git.sourceforge.net/gitroot/emboslab/rtems-4.9.5-emboslab
下载最新的 rtems 4.9.5 在 qemu mini2440 上的移植。
请键入以下命令编译rtems 4.9.5 关于 qemu mini2440 bsp:
cd rtems-4.9.5-emboslab
mkdir mini2440
cd mini2440
../configure --target=arm-rtems4.9 --disable-posix --enable-networking --enable-rtemsbsp=mini2440 --prefix=/opt/rtems-4.9
make all install
编译一下hello_world_c 和ticker等示例吧,运行这些示例的方法请参考其本博的他关于mini2440的博文。
从官方下载network-demos-4.9.4.tar.bz2
tarxjvf network-demos-4.9.4.tar.bz2
cd network-demos-4.9.4
gedit networkconfig.h (需要修改一下改文件,下面有列出)
export RTEMS_MAKEFILE_PATH=/opt/rtems-4.9/arm-rtems4.9/mini2440/
cd http
make
arm-rtems4.9-objcopy -O binary o-optimize/http.exe /tftproot/image.bin
进入qemu文件夹:
./mini2440/mini2440_start.sh
启动qemu,
在 mini2440# 提示符下输入:
tftp 30000100 image.bin
go 30000100
[ 本帖最后由 rickleaf 于 2011-4-11 09:00 编辑 ]
RTEMS网卡驱动移植(续)
[*]ping 10.0.0.100 -s 1000http://hi.csdn.net/attachment/201103/25/0_1301059281ZeqW.gif[*]使用浏览器查看网页http://hi.csdn.net/attachment/201103/25/0_1301059409R40c.gif
[*]查看CPU使用率(第一个超文本链接)http://hi.csdn.net/attachment/201103/25/0_1301059530zwNC.gif
[*]最后,贴上networkconfig.h文件内容:view plaincopy to clipboardprint?
[*]/*[*] * Network configuration -- LOOPBACK ONLY!!![*] *[*] * See one of the other networkconfig.h files for an[*] * example of a system that includes a real NIC and[*] * the loopback interface.[*] *[*] ************************************************************[*] * EDIT THIS FILE TO REFLECT YOUR NETWORK CONFIGURATION *[*] * BEFORE RUNNING ANY RTEMS PROGRAMS WHICH USE THE NETWORK! *[*] ************************************************************[*] *[*] *$Id: networkconfig.h,v 1.14 2008/08/20 22:16:28 joel Exp $[*] */[*]#ifndef _RTEMS_NETWORKCONFIG_H_[*]#define _RTEMS_NETWORKCONFIG_H_[*]/* #define RTEMS_USE_BOOTP */[*]#include <bsp.h>[*]#include <rtems/dhcp.h>[*]#define RTEMS_USE_BOOTP[*]/*[*] * Loopback interface[*] */[*]extern
int rtems_bsdnet_loopattach();[*]static
struct rtems_bsdnet_ifconfig netdriver_config1 = {[*]RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */[*]RTEMS_BSP_NETWORK_DRIVER_ATTACH,/* attach function */[*]NULL, /* No more interfaces */[*]"10.0.0.100", /* IP address */[*]"255.255.255.0", /* IP net mask */[*]NULL, /* Driver supplies hardware address */[*]0, /* Use default driver parameters */[*]0, /* default efficiency multiplier */[*]0, /* default udp TX socket buffer size */[*]0, /* default udp RX socket buffer size */[*]0, /* default tcp TX socket buffer size */[*]0, /* default tcp RX socket buffer size */[*]};[*]/*[*] * Default network interface[*] */[*]static
struct rtems_bsdnet_ifconfig netdriver_config = {[*]"lo0", /* name */[*]rtems_bsdnet_loopattach,/* attach function */[*]&netdriver_config1, /* No more interfaces */[*]"127.0.0.1", /* IP address */[*]"255.0.0.0", /* IP net mask */[*]NULL, /* Driver supplies hardware address */[*]0, /* Use default driver parameters */[*]0, /* default efficiency multiplier */[*]0, /* default udp TX socket buffer size */[*]0, /* default udp RX socket buffer size */[*]0, /* default tcp TX socket buffer size */[*]0, /* default tcp RX socket buffer size */[*]};[*][*]/*[*] * Network configuration[*] */[*]struct rtems_bsdnet_config rtems_bsdnet_config = {[*]&netdriver_config,[*]NULL, /* do not use bootp */[*]0, /* Default network task priority */[*]1024 * 1024, /* Default mbuf capacity */[*]1024 * 1024, /* Default mbuf cluster capacity */[*]"rtems", /* Host name */[*]"nodomain.com", /* Domain name */[*]"127.0.0.1", /* Gateway */[*]"127.0.0.1", /* Log host */[*]{"127.0.0.1" }, /* Name server(s) */[*]{"127.0.0.1" }, /* NTP server(s) */[*]0, /* sb_efficiency */[*]0, /* udp_tx_buf_size */[*]0, /* udp_rx_buf_size */[*]0, /* tcp_tx_buf_size */[*]0 /* tcp_rx_buf_size */[*]};[*]/*[*] * For TFTP test application[*] */[*]#if (defined (RTEMS_USE_BOOTP))[*]#define RTEMS_TFTP_TEST_HOST_NAME "BOOTP_HOST"[*]#define RTEMS_TFTP_TEST_FILE_NAME "BOOTP_FILE"[*]#else[*]#define RTEMS_TFTP_TEST_HOST_NAME "XXX.YYY.ZZZ.XYZ"[*]#define RTEMS_TFTP_TEST_FILE_NAME "tftptest"[*]#endif[*]/*[*] * For NFS test application[*] *[*] * NFS server/path to mount and a directory to ls once mounted[*] */[*]#define RTEMS_NFS_SERVER "192.168.1.210"[*]#define RTEMS_NFS_SERVER_PATH "/home"[*]#define RTEMS_NFS_LS_PATH "/mnt/nfstest"[*]#endif /* _RTEMS_NETWORKCONFIG_H_ */
enjoy it!
(本文原创,转载请注明出处,谢谢)
[ 本帖最后由 rickleaf 于 2011-4-11 09:02 编辑 ]
页:
[1]