EDN首页   博客首页

7

关于投票
windML鼠标OK!

前几天在用windML的时候发现在配置windML加上鼠标就不能正常显示图形,出现黑屏的现象。这几天将windML的DDk看了一下,终于将这个问题搞定了。

1 最基本的还是要将所有的配置选项配置正确,包括windML下的配置(包含鼠标),congfig.h里包含#define INCLUDE_WINDML
#define INCLUDE_WINDML_PS2_POINTE
#define INCLUDE_WINDML_PS2_KEYBOARD

在组件配置的时候,windML下的鼠标要包含,里面的属性名字跟windML下的配置名字相同

2 这就是在你启动以后在shell里用devs看看有没有你的鼠标键盘设备了。如果没有这就说明你的BSP设置有问题(一开始我在uglinit.c的初始化ugl设备的函数单步跟了一下,如果你的不行也可以这样试试)。如果有的话就进去用应用程序测试你的鼠标吧:)

系统分类: 嵌入式
用户分类: windML
标签: windML鼠标OK
来源: 原创
发表评论 阅读全文(1708) | 回复(9)

6

关于投票
windML--接上面文章

4 设置低级驱动模式
设置低级驱动允许传入所有的输入驱动,一般调用原始模式(raw mode)。这么设置是因为高级输入驱动需要对任何传输来原始数据进行处理,打包后作为输入事件。低级驱动传输数据,高级驱动接受数据。低级驱动有不同的操作,所以必须在一个合适的模式。
/* Set device in mode to pass all data – raw mode */
ioctl (pDevice->inputDevice.fd, FIOSETOPTIONS, OPT_RAW);
/* Flush input queue of any stale data */
ioctl (pDevice->inputDevice.fd, FIOFLUSH,0);
/* Scan codes need to be sent verses processed key codes */
ioctl (pDevice->inputDevice.fd, CONIOCONVERTSCAN, FALSE);
/* Initialize the LED to the initialized value */
ioctl (pDevice->inputDevice.fd, CONIOLEDS, pDevice->ledValue);
5 返回驱动结构的指针。如果驱动成功打开,返回UGL_INPUT_DEV的指针return (&pDevice->inputDevice);失败返回NULL

执行驱动控制程序
驱动控制程序提供几种操作使用标准的ioctl函数,有三个参数
第1驱动操作控制块
第2需求类型
第3需求类型包含地参数
具体如下:图


Keyboard LED Control点击看大图
switch (reqType)
{
.
.
.
case ICR_SET_LED: /* Set LED values */
case ICR_CLEAR_LED: /* Clear LED values */
{
UGL_UINT32 leds = *(UGL_UINT32 *)pArg;
int ledValue = 0;
/* generate a device dependent LED value */
if (leds & UGL_KBD_CAPS_LOCK)
ledValue |= UGL_PCKBD_LED_CAPS_LOCK;
if (leds & UGL_KBD_NUM_LOCK)
ledValue |= UGL_PCKBD_LED_NUM_LOCK;
if (leds & UGL_KBD_SCROLL_LOCK)
ledValue |= UGL_PCKBD_LED_SCROLL_LOCK;
/* Adjust representation if setting or clearing LEDs */
if (request == ICR_SET_LED)
pDevice->ledValue |= ledValue;
else
pDevice->ledValue &= ~ledValue;
/* Send request to low-level driver to change the LED values */
ioctl (pDevice->inputDevice.fd, CONIOLEDS, pDevice->ledValue);
}
break;
case ICR_GET_LED_STATE: /* Get state of LEDs */
{
UGL_UINT32 modifiers = 0;
/* Generate LED setting based on the modifier states */
if (pDevice->ledValue & UGL_PCKBD_LED_CAPS_LOCK)
modifiers |= UGL_KBD_CAPS_LOCK;
if (pDevice->ledValue & UGL_PCKBD_LED_NUM_LOCK)
modifiers |= UGL_KBD_NUM_LOCK;
if (pDevice->ledValue & UGL_PCKBD_LED_SCROLL_LOCK)
modifiers |= UGL_KBD_SCROLL_LOCK;
*(UGL_UINT32 *)pArg = modifiers;
}
break;
.
.
.
}
询问鼠标类型
鼠标类型的驱动必须由ICR_GET_PTR_TYPE指出类型例如:
switch (request)
{
.
.
.
case ICR_GET_PTR_TYPE: /* Pointer type query */
{
if(pArg != UGL_NULL)
{
*(int *)pArg = UGL_PTR_TYPE_MOUSE;
return(UGL_STATUS_OK);
}
else
return(UGL_STATUS_ERROR);
}
break;
.
.
.
}
读数据
所有高级输入设备必须响应数据读取要求。输入服务可被select挂起,等待数据被写入设备输入设备读队列。当低级设备驱动唤醒输入服务任务,任务调用合适的输入的设备控制通过ICR_READ请求。
当ICR_READ调用设备控制程序时,从低级驱动读取所有数据。例子如下:
switch (request)
{
case ICR_READ: /* read keyboard data */
{
int readCnt = 0;
/* Get data until no more data is present */
ioctl (pDevice->inputDevice.fd, FIONREAD, (int)&readCnt);
while (readCnt > 0)
{
unsigned char scanCode;
/* Read a code from the keyboard low-level driver */
if (read(pDevice->inputDevice.fd, &scanCode, 1) != 1)
return (UGL_STATUS_ERROR);
/* If received data signifies the start of an extended key,
* then mark that in the process of reading an extended key
* sequence */
if (scanCode == UGL_PCKBD_EXTENDED_KEY)
pDevice->extendedKey = UGL_TRUE;
else if (scanCode != 0x55) /* In test, ignore */
{
UGL_MSG kbdMsg;
/* Create raw keyboard message */
bzero ((char *)&kbdMsg, sizeof (kbdMsg));
kbdMsg.type = MSG_RAW_KBD;
kbdMsg.data.rawKbd.deviceId = &pDevice->inputDevice;
if (scanCode & UGL_PCKBD_MAKE_FLAG)
{
kbdMsg.data.rawKbd.isKeyDown = UGL_FALSE;
scanCode &= ~UGL_PCKBD_MAKE_FLAG;
}
else
kbdMsg.data.rawKbd.isKeyDown = UGL_TRUE;
if (pDevice->extendedKey)
{
kbdMsg.data.rawKbd.isExtended = UGL_TRUE;
pDevice->extendedKey = UGL_FALSE;
}
else
kbdMsg.data.rawKbd.isExtended = UGL_FALSE;
kbdMsg.data.rawKbd.isKeyCode = FALSE;
kbdMsg.data.rawKbd.value.scanCode = scanCode;
/* post message */
uglInputMsgPost (pDevice->inputDevice.inputServiceId,
&kbdMsg);
}
readCnt--;
}
}
break;
.
.
.
}

系统分类: 嵌入式
用户分类: windML
标签: 关于windML
来源: 原创
发表评论 阅读全文(778) | 回复(1)

6

关于投票
windML输入设备的头文件

输入设备的头文件
驱动的头文件包括典型的设备,但是头文件必须包含windML的哪一部分连入驱动的信息和驱动怎么包含配置信息。
设备控制结构
必须定义输入设备控制结构体(作为UGL_INPUT_DEV的第一个元素)如果输入设备不需要其他的数据就如下定义
typedef struct ugl_pc_kbd_device
{
UGL_INPUT_DEV inputDevice; /* Inherits input device structure */
UGL_BOOL extendedKey; /* Extended key receipt */
UGL_BOOL ledControl; /* App/WindML controls LEDs */
UGL_UINT32 ledValue; /* Current LED state */
} UGL_PC_KBD_DEVICE;
这个例子中键盘驱动需要LED中的信息和是否外部的键在执行;因此要包含下面的几项。
配置控制
一个输入驱动可能需要包含来自初始化程序的配置信息。同样配置程序可能需要关于已有驱动的信息。因此,头文件必须包含以下信息
/* Get the Device Driver Configuration Definitions */
#ifndef INCLUDE_PC_AT_KEYBOARD
#define INCLUDE_PC_AT_KEYBOARD
#define BUILD_DRIVER
#include <uglInit.h>
#endif /* INCLUDE_PC_AT_KEYBOARD */
这种情况下,包含uglInit,h提供需要的配置信息
注意:BUILD_DRIVER必须在uglInit,h之前定义。
INCLUDE_PC_AT_KEYBOARD定义了特殊的设备驱动。当写一个新的驱动必须重新定义一个特殊的设备驱动宏。
除此外设备驱动在头文件里包含设备驱动配置参数设备驱动必须包含以下的参数
SYS_KEYBOARD_DRIVER提供输入驱动的数据结构来辨别键盘输入设备的入口指针
SYS_POINTER_DRIVER
以下程序提供初始化程序指针
extern UGL_INPUT_DRV uglPs2PtrDriver;
#define SYS_POINTER_DRIVER &uglPs2PtrDriver
相关数据结构在uglPs2PtrDriver例子中。
一般资源文件格式
执行以下三种操作
open打开一个低级驱动,设置设备驱动的可能模式,初始化设备控制结构
close关闭一个低级驱动释放开的资源
control一般驱动控制操作包括conhdiji驱动里读数据和设置键盘LED的值
Input Driver Structure
UGL_INPUT_DRV uglPcKbdDriver =
{
(UGL_INPUT_DEV_OPEN)uglPcKbdOpen, /* Open driver API */
(UGL_INPUT_DEV_CLOSE)uglPcKbdClose, /* Close driver API */
(UGL_INPUT_DEV_CONTROL)uglPcKbdControl /* Control driver API */
};
头文件必须包含UGL_INPUT_DRV,可以运行这些程序
执行驱动打开程序
当程序运行uglInitializ的时候初始化windML。在uglInitializ中,调用uglInputDevOpen( )打开输入驱动程序。
当输入驱动成功打开的以后,驱动打开程序返回UGL_INPUT_DEV数据结构的指针。如果驱动初始化设备失败,就返回NULL。
驱动打开程序包括以下输入参数:
第一个参数是低级驱动的名字,驱动接收原始数据
第二个参数是输入驱动结构UGL_INPUT_DRV的指针
需要驱动打开的程序
驱动打开的程序需要分为下面几步:
1 分配驱动控制结构
UGL_LOCAL UGL_INPUT_DEV * uglPcKbdOpen
(
char * pDevName, /* name of the device */
UGL_INPUT_DRV * pDriver /* input driver */
)
{
UGL_PC_KBD_DEVICE * pDevice;
/* allocate the device descriptor */
pDevice = (UGL_PC_KBD_DEVICE *) UGL_CALLOC (1,
sizeof (UGL_PC_KBD_DEVICE));
if (pDevice == UGL_NULL)
return (UGL_NULL);
驱动控制结构用UGL_CALLOC程序分配,确保能从WindML内存池中分配到所需的内存。
2 打开低级驱动
/* open the device */
pDevice->inputDevice.fd = open (pDevName, 0, 0);
if (pDevice->inputDevice.fd < 0)
{
UGL_FREE (pDevice);
return (UGL_NULL);
}
打开文件的文件描述符存储在输入设备结构中。如果打开失败,分配的内存被释放,返回NULL指针。
3 初始化驱动控制结构
包括两部分初始化:UGL_INPUT_DEV和在开发下特殊的数据,UGL_INPUT_DEV必须初始化以下数据域:
文件描述符fd在第二步被设置
设备类型
UGL_DEVICE_KEYBOARD
A keyboard.
UGL_DEVICE_POINTER_ABSOLUTE
A pointer device that generates an absolute location on the display
screen. A touchscreen is an example of an absolute pointing device.
UGL_DEVICE_POINTER_RELATIVE
A pointer device that generates a relative location from the previous
reported location, such as a mouse.
驱动程序结构
驱动程序结构是UGL_INPUT_DRV数据结构的一个指针(由第二那个参数传入)。
/* Initialize required device data */
pDevice->inputDevice.deviceType = UGL_DEVICE_KEYBOARD;
pDevice->inputDevice.pDriver = pDriver;
/* Initialize driver specific data for keyboard */
pDevice->ledValue = 0;
pDevice->extendedKey = FALSE;
pDevice->ledControl = TRUE;

 

系统分类: 嵌入式
用户分类: windML
标签: windML输入设备的头文件
来源: 原创
发表评论 阅读全文(1143) | 回复(1)

5

关于投票
windML输入设备

 

 

点击看大图

低级别输入驱动
低级别输入驱动作为IO驱动执行,通常在系统内核配置。这个驱动当初始化的时候连接内核系统的IO系统。它的响应包括以下几方面:
初始化设备控制器和输入设备
通过设备控制器生成中断句柄
从输入设备接收原始数据并且降队列用IO系统传给高级驱动。数据排队完,输入设备激活使用select机制
从高级驱动接收命令和应答。例如在键盘控制LED
开发一个低级输入驱动,必须理解怎样微操作系统写IO驱动,并且理解设备控制器和你所开发的输入设备。
经常,输入设备连接串行接口,例如Vxworks提供的标准串行设备。例如,触摸屏经常通过串口能被连接到标准的串行设备如/tyCo/1。
高级输入驱动
高级输入驱动主要响应接收从低级输入驱动传来的原始输入数据,打包作为输入消息,并将消息放到消息队列里。

执行低级输入驱动
低级输入驱动是标准繁的IO系统驱动提供基础的IO接口open,close,read,write,ioctl
除此之外,驱动必须提供select的支持,提供给检测输入数据用。
当执行低级输入设备时,为一般操作系统,不同的硬件,不同的目标板设计。你能够通过写不同硬件结构驱动代码达到目的。怎么编驱动和怎么使用windML的硬件抽象层,看12
对vxworksIO驱动的一般技术在vxworks programmers guids:IO系统
既然vxwork的styLib提供许多低级驱动的功能,建议使用tyLib的优势。通过这个,你的驱动不用控制读写队列或select程序。这将使开发低级驱动变得很简单。

设备的程序数据
低级驱动不能从输入设备中断数据。可以接收数据并且作为原始数据传给高级输入驱动,没有调整输入结构。例如,一个键盘设备通常发送一列代码包括key up和key down。每一个键的代码需要传给高级驱动。
发送数据到设备
一个低级的设备驱动不能利用write机制从高级的驱动设备接收任何数据。这可能产生输入设备异常。一些需要高级设备驱动写不同的操作模式信息。当为一个特殊的硬件开发一个输入驱动时,你可能需要高级设备驱动网低级设备驱动写程序给特殊需求的设备。
设备控制
低级输入设备需要为依赖于操作的输入设备完成ioctl功能。ioctl功能整个依赖设备类型和控制的不同。例如,键盘输入设备有一个为控制LED的ioctl功能。对于vxworks,ioctl设备必须提供有用的select信号。
完成高级输入设备
以下是写高级驱动的步奏
为windML结构中的的驱动创建资源和头文件。一个头文件甚至需要作为一个二进制驱动,因为配置程序需要在输入设备的头文件中包含子女子。
创建open等程序
创建资源和头文件
包含的文件夹
installDir/target/src/ugl/driver/keyboard
The source file for all keyboard drivers.
installDir/target/h/ugl/driver /keyboard
All header files for the keyboard drivers.
installDir/target/src/ugl/driver/pointer
The source file for all pointer drivers.
installDir/target/h/ugl/driver /pointer
All header files for the pointer drivers.
增加一个新的键盘或鼠标驱动,增加新的资源到路径下。就不需要配置makefile,makefile可以编译这个目录下的所有资源。

系统分类: 嵌入式
用户分类: windML
标签: windML输入设备
来源: 原创
发表评论 阅读全文(1026) | 回复(2)

8

关于投票
windML资料

小鱼整理的windML资料,希望对大家有用:)

rar

系统分类: 嵌入式
用户分类: windML
标签: windML资料
来源: 整理
发表评论 阅读全文(1049) | 回复(0)

7

关于投票
xiaofish调windML
今天下午我又根据几个网友给我提的建议继续调试windml,因为我对这个东东还抱有一丝希望!
首先学会了单步调试程序,单步跟踪了一下uglDemo,发现一运行到uglInit程序就飞了,跑出一个汇编的程序窗口,“可靠树”告诉我可能是因为我的源码不全,当时郁闷死!可还是没死心!
然后根据“xx ”给我提的建议我把windml卸了,重装!我上次装windml时让选Tornado版本时我把所有的都选上了(有点贪婪啊),这次只选了Tornado2.2,然后重新编译windml,选了No Pointer 并把keyboard的Name改成了/pcConsole/0(“ xx”告诉我这样改的),在等待编译完成的过程中又看到“xxx”给我的网页里有这样一段话:

2.8.1 Linking the 2D Library

2D library可以通过两种方法和VxWorks image相连。

1.将全部的2D层连接到VxWorks image中。(complete 2D library)

它允许WindML应用程序在目标机启动后并发的下载。这种模式在Vxworks/WindML包含了全部的WindML 2Dg功能后,允许任何的WindML应用程序动态的下载

1.   只连接必需的2D功能

这种模式需要将WindML编译进VxWorks,除WindML应用程序之外。这个结果在一个小的Vxworks/WindML image中。

注意:如果已经连接了一个更高一层的图形产品如:Zinc或者PersonalJWorks,就应该选择necessary 2D

library而不是complete 2D library.

所以我就把libwndml.a加入到VxWorks的EXTRA_MODULES里,然后重新编译VxWorks,然后继续单步调试程序,竟然就没有汇编窗口蹦出来了,然后就看到有图形显示了,然后就可以响应键盘了!

xiaofish的经验也许对大家有帮助啊!

系统分类: 嵌入式
用户分类: windML
标签: xiaofish调windML
来源: 原创
发表评论 阅读全文(797) | 回复(1)

12

关于投票
vxworks如何才能操作WindML显示部分的存储空间

(UGL_UINT32)Vesa_VideoDriver->genDriver.fbAddres在初始化设备后将这个值附给一个全局变量,再打印出来就行.这个地址就是初始地址.其实在你应用程序初始化设备后会在Shell里看见打印出一串地址(我的工控板是0x40800000)这就是起始地址,后面还有显存大小,是否使用双缓存.下面是初始化你的图形设备的程序: 

if (uglInitialize() == UGL_STATUS_ERROR)/*初始化设备*/
 return; 
  pRegistryData = uglRegistryFind (UGL_DISPLAY_TYPE, 0, 0, 0);/*找到设备注册信息*/
    if (pRegistryData == UGL_NULL)
        {
 printf("Display not found. Exiting.\n");
 uglDeinitialize();
 return;
 }
    devId = (UGL_DEVICE_ID)pRegistryData->id;/*设备ID*/

    pRegistryData = uglRegistryFind (UGL_INPUT_SERVICE_TYPE, 0, 0, 0); /*找到输入设备*/  
    if (pRegistryData == UGL_NULL)
   {
     printf("Input service not found. Exiting.\n");
     uglDeinitialize();
     return;
   }
    inputServiceId = (UGL_INPUT_SERVICE_ID)pRegistryData->id;/*输入设备ID*/

后直接往初始地址地址就能写值了!

系统分类: 嵌入式
用户分类: windML
标签: vxworks如何才能操作WindML显示部分的存储空间
来源: 无分类
发表评论 阅读全文(2139) | 回复(21)

36

关于投票
VxWorks丰富的定时管理和时钟管理

VxWorks提供丰富的定时管理和时钟管理,主要应用在以下几个方面:

? 维护系统日历时钟

? 在任务等待信号量、消息、事件(VxWorks5.5版本以上)或内存段时的超时处理。(系统提供的函数调用都有关于timeout的参数设置。)

? 以一定的时间间隔或在特定的时间唤醒或发送告警到一个任务。

? 处理任务调度中的时间片轮转。

VxWorks系统这些功能都依赖于周期性的定时中断,离开实时时钟或定时器硬件就无法工作。介绍几个常用的系统调用:

l sysClkConnect( )――连接系统时钟中断服务程序(sysLib.h)

函数原型:――connect a routine to the system clock interrupt
STATUS sysClkConnect
(
FUNCPTR routine, /* routine called at each system clock interrupt */
int arg /* argument with which to call routine */
)

l sysClkRateSet( )――设置每秒钟系统时钟中断次数(既每秒钟的tick数)(sysLib.h)
函数原型:――set the system clock rate
STATUS sysClkRateSet
(
int ticksPerSecond /* number of clock interrupts per second */
)

l sysClkEnable ( )――使能系统时钟中断(sysLib.h)

函数原型:――turn on system clock interrupts

void sysClkEnable (void)

系统定时器的设置是在usrConfig.c中通过usrRoot( )函数完成的,主要就是调用以上三个函数,代码如下:

/* set up system timer */

sysClkConnect ((FUNCPTR) usrClock, 0); /* connect clock ISR */

sysClkRateSet (SYS_CLK_RATE); /* set system clock rate */

sysClkEnable (); /* start it */

其中usrClock( )也是在usrConfig.c中定义的,函数只是通知系统内核时钟tick。

void usrClock ()

{

tickAnnounce (); /* announce system tick to kernel */

}

(有关tickLib.h中的函数以后再介绍)

而系统时钟频率SYS_CLK_RATE的值在congfigAll.h中定义为60,代码如下:

#define SYS_CLK_RATE 60 /* default system clock rate */

你可以通过改这个值来自己设置系统时钟中断频率,一般在60到100,但不能大于600。SYS_CLK_RATE只设置的过大会增加任务切换开销。

l sysClkRateGet( )――得到每秒钟系统时钟中断次数(既每秒钟的tick数)(sysLib.h)

函数原型:――get the system clock rate

int sysClkRateGet (void)

[此贴子已经被作者于2004-5-31 17:13:36编辑过]
--------------------------------------------------------------------------------

学习总结:VxWorks的定时与时钟管理2

http://bbs.edw.com.cn/dispbbs.asp?boardID="3"&ID="29415"&page="1"

自己的一个小程序:(如何使用sysCkRateSet和sysClkRateGet)

/**********************************/
#i nclude "vxWorks.h"
#i nclude "sysLib.h"

#i nclude "stdio.h"
void test()
{
int TimeRate,NumB;
TimeRate = 100;
if(sysClkRateSet(TimeRate) ==ERROR)
{
printf("Error in setting rate!\n");
}
NumB = sysClkRateGet();
printf("NumB = %d\n",NumB);
}
运行结果:
-> test
NumB = 100
value = 11 = 0xb = __major_os_version__ + 0x7
l tickAnnounce( )――通知系统内核时钟tick
函数原型:――announce a clock tick to the kernel
void tickAnnounce (void)
它被usrConfig.c中的usrClock( )调用,而usrClock( )又是系统时钟中断服务程序,想让应用程序运行在系统时钟中断级,则可将其加在ursClock程序里。
l tickSet( )――设置内核时钟计数器值(内核tick的数)
函数原型:――set the value of the kernel's tick counter
void tickSet
(
ULONG ticks /* new time in ticks */
)
l tickGet( )――得到内核时钟计数器值
函数原型:――get the value of the kernel's tick counter
ULONG tickGet (void)
下面两个例子:
/**********例一:用tickGet获得现在内核tick定时器的tick数******************/
#i nclude "vxWorks.h"
#i nclude "tickLib.h"
#i nclude "stdio.h"
#i nclude "taskLib.h"
#i nclude "logLib.h"
void test()
{
ULONG TickCounts;
for(int i="0";i<5;i++)
{
TickCounts = tickGet();
logMsg("TickCounts = %d\n",TickCounts,0,0,0,0,0);
taskDelay(100);
}
}
运行结果:(在目标仿真器上输出)
0x12892b8 (t12): TickCounts = 299830
0x12892b8 (t12): TickCounts = 299930
0x12892b8 (t12): TickCounts = 300030
0x12892b8 (t12): TickCounts = 300130
0x12892b8 (t12): TickCounts = 300230
如果将上面的logMsg换为printf,则输出在shell中(注意两种输出的区别)。
/***********例二:tickSet和tickGet的使用例程************************/
#i nclude "vxWorks.h"
#i nclude "tickLib.h"
#i nclude "stdio.h"
#i nclude "taskLib.h"
void test()
{
ULONG TickCountSet = 0;
tickSet(TickCountSet);
for(int i="0";i<5;i++)
{
ULONG TickCounts = tickGet();
printf("TickCounts = %d\n",TickCounts);
taskDelay(100);
}
}
运行结果:
-> test
TickCounts = 0
TickCounts = 100
TickCounts = 200
TickCounts = 300
TickCounts = 400
value = 0 = 0x0