打印
[ZLG-ARM]

UCOS模拟硬件中断的设想(纯粹学习,只想想思路,偶是菜菜

[复制链接]
3354|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
crazyteam|  楼主 | 2008-1-9 11:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    比如说,我用LPC2104,但是我总共需要4个串口,那么只能模拟串口出来了;当然高人会说,你笨啊,不知道选个串口多的片子啊!我只能先说,高人,资源是有限的,需求是无限的,选个片子解决了,难保下次遇到要8个串口呢?扩串?
    我只是想用这个来做个探讨,呵呵
    硬件编写和调试我觉得都很简单,只要串口时序对,TXD和RXD都可以OK
    如果是在LPC2104上不用操作系统,裸奔的话,问题也不大
    但是如果用UCOS,应该怎么做呢?而且要和ZLG串口中间件的方法比较类似
    我初步的想法是,发送共用UARTWRITE(),里面直接就操作I/O了;接收采用通用的C51的办法,用一个外部中断EXINT0做起始位的检测,TIMER1做采样(TIMER0是系统时钟);底层按网上有的C51的模拟串口编写;
    麻烦的事情来了,接收完了,怎么通知UCOS呢?
    我想采用软中断,把0x08通道分配给这个模拟的串口,但是中断程序估计只能用ASM编了,明说,不知道怎么下手
    如果不用软中断,那么只能一直在UCOS的TASK里等待信号量的方式,但是这样一来,和我设想的模拟串口要和真正的串口一样操作就不能实现了,也就是说,模拟串口的接收,在系统的层面,也是采用中断接收的方式进行的。。。
    如果上面两个都是错误的,有其他办法么?
    期待中。。。。。。。。。。

相关帖子

沙发
crazyteam|  楼主 | 2008-1-9 14:12 | 只看该作者

可能,我对软中断的理解是错误的?

    但是,从所有的资料上来看,软中断确实是从驱动到系统的一个连接方法哦

使用特权

评论回复
板凳
crazyteam|  楼主 | 2008-1-9 16:46 | 只看该作者

自己灌一个,不要沉了

    大家都只关心解决自己的问题?
    不多想想的么?说不定以后自己就会遇到资源不够要做模拟中断的哦。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

使用特权

评论回复
地板
王紫豪| | 2008-1-9 17:24 | 只看该作者

打死我也不会用软件模拟串口的!

使用特权

评论回复
5
crazyteam|  楼主 | 2008-1-9 17:31 | 只看该作者

晕,4楼这么坚决

    为什么不用?
    毕竟NXP的片子好多管腿都是复用的,而且这样做一次不敢说对ARM和UCOS精通,至少能对运转的流程有个比较清晰的了解,也有好处
    先用2104的开发板做做实验吧,我觉得使用软中断的方式应该是可行的,可怜又要用汇编了

使用特权

评论回复
6
xwj| | 2008-1-9 17:32 | 只看该作者

是啊,大家来把王紫豪打死吧...

呵呵^_^

使用特权

评论回复
7
crazyteam|  楼主 | 2008-1-9 17:48 | 只看该作者

留口气.......

    要不他BOSS要拉我们当壮丁......
    

使用特权

评论回复
8
wlsui| | 2008-1-9 21:45 | 只看该作者

置位VICSoftInt里的相应位

要用中断通知上层程序? 楼主看下VICSoftInt这个寄存器吧,看完后你就找到答案了
置位VICSoftInt里的相应位

当然了,由于与本身的UART中断号相同,所以还得给一个标志位,
如果置位VIC#6,即UART0通道,则需要在UART0的中断服务程序里判断一下该标志位,以确认是UART0的中断还是你模拟的UART的中断

不过个人觉得,费那么大劲还不如用信号量
而且,你不是在外部中断里接收数据吗,接收完后直接从外部中断服务程序里发个信号量给OS不就行了---就算你另外再产生了一个UART中断,最后还不是发送信号量给OS?

使用特权

评论回复
9
crazyteam|  楼主 | 2008-1-10 08:52 | 只看该作者

谢谢8楼,一会去看下你说的VICSoftInt

    我想过直接用信号量,但是好象不符合操作系统的编码规则。。。。。
    我费劲想这样做是想把模拟的串口封装成一个标准串口,这样OS调用的时候就和调用标准串口一样的函数,也就是说OS用一个API就可以既调用标准串口,也能调用模拟的串口,在OS的层面上来说,用同样的驱动就可以了,这样也符合操作系统的要求——不理会硬件是怎么工作的,只需要按标准API调用,这样的移植性应该比较好。
    不过这个只是我个人的看法,不知道对操作系统的理解是不是正确的

使用特权

评论回复
10
wlq_9| | 2008-1-10 09:43 | 只看该作者

支持王紫豪

不过前提是在ARM的ucos平台下,主要原因是:ARM的中断响应时间不好精确的计算,还有就是资源占用太多.模拟的串口严重影响系统的响应时间.要用四串口,选一个带四串口的ARM即可,价格又差不多.
当然,对于成本极其敏感的项目,也还是可以用的,谁叫现在市场这么难做呢.

使用特权

评论回复
11
crazyteam|  楼主 | 2008-1-10 10:20 | 只看该作者

谢谢wlsui

VICSoftInt虽然叫Software Interrupt Register,但是和我想的软中断好象不是一回事情,VICSoftInt还是硬件层面上产生的中断,而我想的软中断是这样的东西:
__swi(0x02) void OS_ENTER_CRITICAL(void);

按我的想法,要做模拟串口的软中断,应该首先
1、在OS_CPU.H里增加下面代码
__swi(0x08) void VIRTUAL_UART10(void);//软中断通道号//
2、在OS_CPU_C.C里void SWI_Exception()增加下面代码
switch(SWI_Num)
{
    case 0x02:........break;
    .
    .
//对应通道号的处理//
    case 0x08:
    __asm{(里面还不知道怎么写,呵呵)}break;
    .
    .
}
3、在EXTINT1(也就是模拟接收的外部中断处)添加
VIRTUAL_UART10();//接收完成后跳转到软中断处
4、在IRQ.S里增加
//指定C程序的中断入口//
Uart10_Handler  HANDLER Uart10_Exception
5、在自己的程序里编写中断程序
void Uart10_Exception(void)
{
//等待信号量或者直接取EXTINT1里获得的串口数据//
........
}

不知道这样的流程是否是对的

使用特权

评论回复
12
crazyteam|  楼主 | 2008-1-10 10:31 | 只看该作者

不是成本压力,是学习压力,呵呵

wlq_9 发表于 2008-1-10 09:43 ZLG-ARM ←返回版面    

10楼: 支持王紫豪 

不过前提是在ARM的ucos平台下,主要原因是:ARM的中断响应时间不好精确的计算,还有就是资源占用太多.模拟的串口严重影响系统的响应时间.要用四串口,选一个带四串口的ARM即可,价格又差不多.
当然,对于成本极其敏感的项目,也还是可以用的,谁叫现在市场这么难做呢. 
 
对,我觉得王紫豪和wlq_9两位兄台说的是对的
只是我发这个讨论的目的不是针对任何的项目,我只是想搞清楚UCOS与硬件底层间通讯的接口方式,也就是说,做为一个做硬件,调板子出身的人来说,关注的不是在UCOS上怎么来编程,而是硬件和操作系统是怎么对接的,也就是所谓的驱动程序怎么写。
还是那句话,4串的片子很多,但是万一你的项目有个很古怪的接口要求必须要求你模拟I/O的方式来对这个接口操作呢?而且ZLG没有驱动,那你不是一样要写驱动?
我觉得这个思路至少来说可以做到有备无患,以后万一用到这方面的需求至少很快可以想起来,哦,可以这样来做

使用特权

评论回复
13
crazyteam|  楼主 | 2008-1-10 11:24 | 只看该作者

还有,我觉得如果采用软中断的话对系统时间影响是最小的

个人认为,ARM的中断时间和OS是没关系的,要不ARM怎么可能给出那么多中断源?所以“模拟的串口严重影响系统的响应时间”我不太同意,当然如果接口做好了我可以实验下再看是不是严重影响系统响应时间。

资源占用是事实。。。。。

ARM中断响应时间是比较准的,当然不是指在OS上,而是脱离OS的底层操作,我用OS,底层I/O模拟串口,TXD可以到115200,RXD可以到38400,现在唯一的问题就是数据怎么能用标准串口一样的方式传到OS层。

使用特权

评论回复
14
wlq_9| | 2008-1-10 11:49 | 只看该作者

如果串口要准确

那么,要不就是关中断,要不就是把你这个模拟串口所占用的中断放到系统最高优先级.第一个影响是非常明显的,第二个的话也不会少.想想看为什么ARM会为串口做FIFO,就是为了减少资源占用.
你所说的那个问题极其简单,收到一个或者一帧数据了,用邮箱,信号量,队列都可以传递给任务.任务中只负责等待这个消息,收到消息处理即可.

使用特权

评论回复
15
crazyteam|  楼主 | 2008-1-10 12:02 | 只看该作者

串口模拟是占用资源

“现在唯一的问题就是数据怎么能用标准串口一样的方式传到OS层。”
指的是把模拟串口封装成和标准串口一样,所以专门开个任务来等待信号量没在我考虑范围内
我考虑的是模拟串口的用法要和标准串口一样,以中断的方式来接收数据,虽然用中断的方式接收了数据最后还是要用邮箱,信号量,队列传递给任务,但是用中断的方式进行我可以完全使用标准串口的API来进行,也就是说,最后想要的结果是模拟串口封装成标准串口的使用方式。

使用特权

评论回复
16
wlq_9| | 2008-1-10 13:03 | 只看该作者

选一个没用的中断

把这个中断作为你新扩展的串口中断.中断的触发由你的虚拟串口驱动来完成.对应用层来说,它就是一个"串口中断".

搞这个真无聊,除非项目确实需要了,不然别折腾这个东西了.

使用特权

评论回复
17
crazyteam|  楼主 | 2008-1-10 14:05 | 只看该作者

呵呵,谢谢,现在正好无聊

你的办法8楼也提过,不过我还是有自己的想法
不麻烦了,我自己再想想,做个实验验证下自己这样想能不能实现先
谢谢各位。如果有结果发个mcp给大家当个乐子

使用特权

评论回复
18
crazyteam|  楼主 | 2008-1-10 17:07 | 只看该作者

晕了,刚才发的调过的东东怎么没了呢?

测试测试,权当水帖

使用特权

评论回复
19
crazyteam|  楼主 | 2008-1-10 17:17 | 只看该作者

测试通过,再发软中断这条路是通的。。。。。

在LPC2104上做了个小测试,在TASKKEY里检测按键KEY3,按下,跳入自己定义的中断程序,使能/禁止BEEP

//OS_CPU.H中增加了验证软中断的通道代码2008-01-10增加// 
__swi(0x08) void Virtual_UART10(void);        /*  设置中断的通道号  */
/////////////////////////////////////////////////

//os_cpu_c.c中增加了验证软中断的通道代码2008-01-10增加//  
extern  void    Uart10_Exception(void);   
//Uart10_Exception的定义在main.c里//
/////////////////////////////////////////////////////
void SWI_Exception(int SWI_Num, int *Regs)
{
    OS_TCB   *ptcb;
    
    switch(SWI_Num)
    {
        ...........
//os_cpu_c.c中增加了验证软中断的通道代码2008-01-10增加//            
        case 0x08:                      
            __asm
            {
                BL    Uart10_Exception    
//进入自己定义的软中断的服务程序//
            }
            break;     
        ............
    }
}
//////////////////////////////////////////         

//main.c中增加了验证软中断的通道代码2008-01-10增加//   
void TaskKey1 (void *pdata)
{
    pdata = pdata;
    
    for (;;)
    {
        OSTimeDly(OS_TICKS_PER_SEC / 50);               // 延时20毫秒
        if ((IO0PIN & KEY1) != 0)
        {
            continue;
        }
        OSTimeDly(OS_TICKS_PER_SEC / 50);               // 延时20毫秒
        if ((IO0PIN & KEY1) != 0)
        {
            continue;
        }
        OSTaskResume(0);
        while ((IO0PIN & KEY1) == 0)
        {
            Virtual_UART10();   //进入自己的定义的软中断通道号//
            OSTimeDly(OS_TICKS_PER_SEC / 50);           // 延时20毫秒
        }
    }
}

void    Uart10_Exception(void)
{
    if((IO0PIN & BEEP) == 0)
        IO0SET  = BEEP;
    else
        IO0CLR  = BEEP;
}   
//////////////////////////////////////////////////

每次按键都会让BEEP响或者不响(没加按键判断,所以一直按BEEP会短促响)

就是不知道这样稳定性到底如何
汗,现在看回去,觉得自己够无聊。。。。。。。。

使用特权

评论回复
20
wlsui| | 2008-1-10 20:52 | 只看该作者

对你真无语了~~~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

17

帖子

0

粉丝