打印

51基于实时系统的编程

[复制链接]
楼主: zhouwenbin1989
手机看帖
扫描二维码
随时随地手机跟帖
21
16# ayb_ice  
请问在哪可以得到TINY的全部源代码?
zhouwenbin1989 发表于 2011-3-30 22:08

KEIL的安装目录下
C:\Keil\C51\RtxTiny2\SourceCode
没有必要源代码,是汇编的,原理可不简单,知道怎么用就可以了,
看例程
C:\Keil\C51\RtxTiny2\Examples
帮助文档

未命名.JPG (164.97 KB )

未命名.JPG

使用特权

评论回复
22
刘前辈| | 2011-3-31 09:22 | 只看该作者
#19
c51中局部变量在寄存器用完后分配在固定地址怎么理解,是在DATA,IDATA,XDATA哪一块中。small rtos是如何改变这种存储的,汇编吗?


19楼说的是形参吧?否则应该说“c51中局部变量在寄存器用完后分配在固定地址区域怎么理解……”是吗?

这个区域当然指动态共享覆盖区,用户程序一旦经过编译/连接,这段共享覆盖区(固定大小字节)就被分配固定地址了(定位了)。——分配在静态存贮区下面。

、、

使用特权

评论回复
23
刘前辈| | 2011-3-31 09:42 | 只看该作者
哪一块?可以按下图选择默认。当然也可以专门说明:例如:
f1( ) large      // 局部变量i 定义在XDATA
{ char i;
}

使用特权

评论回复
24
刘前辈| | 2011-3-31 09:52 | 只看该作者
small rtos  当然要看它的PCB定义说明,PCB不就是一个结构么。举例:
data  struct_PCB;

当然51结构任务PCB总是定义在data区,否则就太慢了。

使用特权

评论回复
25
zhouwenbin1989|  楼主 | 2011-3-31 13:12 | 只看该作者
18# 刘前辈

把系统节拍调整到50ms感觉不可行,那样按键之类的应该会反应迟钝了。他不希望被切换,但实际上他是一定要被切换的,要不他要写几百ms。资源保护,打断他的任务好像都不会对1602资源进行操作,这样也要保护吗?

使用特权

评论回复
26
zhouwenbin1989|  楼主 | 2011-3-31 13:34 | 只看该作者
本帖最后由 zhouwenbin1989 于 2011-3-31 13:48 编辑

24# 刘前辈
前辈能帮我再看下这个软定时器吗?


#define  IN_SOFT_TIMER
#include "config.h"
                                                    /* 软定时器的数据结构 */
typedef SOFT_TIMER_MEM_SEL struct _TySoftTimerData
{
    uint8 Falg;                                     /* 软定时器状态 */
    uint16 DelayTime;                               /* 软定时器运行时间 */
    void (const * Fuction)(void);                   /* 软定时器溢出调用的函数 */
};
#if MAX_SOFT_TIMER > 0
uint16 SoftTimerCnt;                                /* 辅助定时器 */
uint16 SoftTimerThisDelay;                          /* 辅助定时器初始值 */
struct _TySoftTimerData SOFT_TIMER_MEM_SEL SoftTimerData[MAX_SOFT_TIMER];

        void SoftTimerSum(void)    //每次系统节拍处理时调用的函数,一个辅助定时器
{        
    if( --SoftTimerCnt == 0)
    {
        OSIntSendSignal(SOFT_TIMER_TASK_ID);
    }
}
        void InitSoftTimer(void)//初始化软定时器模块
{
    uint8 i;
   
    OS_ENTER_CRITICAL();
    for (i = 0; i < MAX_SOFT_TIMER; i++)
    {
        SoftTimerData.Falg = 0;
        SoftTimerData.DelayTime = 0;
        SoftTimerData.Fuction = NULL;
    }   
   
    OS_EXIT_CRITICAL();
}
        
uint8 SoftTimerRun(uint8 Index, uint16 Delay, void (const * Fuction)(void))//运行一个软定时器
{
#if EN_SOFT_TIMER_CHK > 0
    if (Index >= MAX_SOFT_TIMER)
    {
        return NOT_OK;
    }
#endif
   
    if (Delay != 0 && Fuction != NULL)
    {
        OS_ENTER_CRITICAL();
        SoftTimerData[Index].Fuction = Fuction;
        SoftTimerThisDelay -= SoftTimerCnt;
        SoftTimerCnt = 0;      
        SoftTimerData[Index].DelayTime = Delay + SoftTimerThisDelay;
        SoftTimerData[Index].Falg &= ~SOFT_TIMER_TIMER_OUT;
        SoftTimerData[Index].Falg |= SOFT_TIMER_TIMER_RUN;
        OS_EXIT_CRITICAL();
        OSSendSignal(SOFT_TIMER_TASK_ID);
        return SOFT_TIMER_OK;
    }
    else
    {
        return NOT_OK;
    }
}
        uint8 SoftTimerStop(uint8 Index)//停止一个正在运行的软定时器
{
#if EN_SOFT_TIMER_CHK > 0
    if (Index >= MAX_SOFT_TIMER)
    {
        return NOT_OK;
    }
#endif
   
    OS_ENTER_CRITICAL();
    SoftTimerData[Index].DelayTime = 0;
    SoftTimerData[Index].Fuction = NULL;
    SoftTimerData[Index].Falg &= ~(SOFT_TIMER_TIMER_OUT | SOFT_TIMER_TIMER_RUN);
    OS_EXIT_CRITICAL();
    return SOFT_TIMER_OK;
}
        void SoftTimer(void)  //软定时器管理任务
{
    uint16 ThisDelay;
    uint8 i;
   
    SoftTimerCnt = 0;
    while (1)
    {
        OS_ENTER_CRITICAL(); //  找到定时最短的定时器
               ThisDelay = -1;
        for (i = 0; i< MAX_SOFT_TIMER; i++)
        {
            if (SoftTimerData.DelayTime != 0 &&
                SoftTimerData.DelayTime < ThisDelay)
            {
                ThisDelay = SoftTimerData.DelayTime;
            }
        }
       //  计算等待时间
        if (ThisDelay > -SoftTimerCnt)
        {
            SoftTimerCnt += ThisDelay;
        }
        else
        {
            SoftTimerCnt = 1;
        }
        SoftTimerThisDelay = ThisDelay;
        
        OSWait(K_SIG,0); //前面关中断到这句话后面才打开,中断都关了,那定时器怎么能唤起任务。??????
        ThisDelay = SoftTimerThisDelay;
        
        //  查询定时到的软定时器
        for (i = 0; i < MAX_SOFT_TIMER; i++)
        {
            SoftTimerData.Falg &= ~SOFT_TIMER_TIMER_OUT;
            if (SoftTimerData.DelayTime != 0)
            {
                if (SoftTimerData.DelayTime <= ThisDelay)
                {
                    SoftTimerData.DelayTime = 0;
                    if (SoftTimerData.Fuction != NULL)
                    {
                        SoftTimerData.Falg |= SOFT_TIMER_TIMER_OUT;
                    }
                }
                else
                {
                    SoftTimerData.DelayTime -= ThisDelay;
                }               
            }
        }
        SoftTimerThisDelay = 0;
        OS_EXIT_CRITICAL();
       //  执行软定时器指定的任务
        for (i = 0; i < MAX_SOFT_TIMER; i++)
        {
            if (((SoftTimerData.Falg & SOFT_TIMER_TIMER_OUT) != 0) &&
                (SoftTimerData.Fuction != NULL))
            {
                SoftTimerData.Falg &= ~SOFT_TIMER_TIMER_OUT;
                SoftTimerData.Fuction();
            }
        }
    }
}


还有这里,在节拍函数中完成系统定时的计算和软定时器计数器的计算
                /* 将函数SoftTimerSum()挂接到函数OSTimeTick()的代码*/
#ifdef IN_OS_CORE
#define OSTimeTick    _OSTimeTick
#else
extern void _OSTimeTick(void);
#define OSTimeTick    SoftTimerSum(),_OSTimeTick
#endif

这不是条件编译码,如果编译只能编译其中一块,另外一个文件中定义了IN_OS_CORE那么编译#define OSTimeTick    _OSTimeTick;
extern void _OSTimeTick(void);
#define OSTimeTick    SoftTimerSum(),_OSTimeTick这两句没法编译那怎么能将原来的OSTimeTick中包含SoftTimerSum(),_OSTimeTick。而且中间怎么是逗号啊。难道不是分号码。这样做怎么实现的两个函数挂接在一起啊。

希望前辈能抽空帮我分析分析,感激不尽

#endif

使用特权

评论回复
27
刘前辈| | 2011-3-31 17:55 | 只看该作者
本帖最后由 刘前辈 于 2011-3-31 17:57 编辑

这里j 没保护,试试修改一下这里的j;

  void KeyHandle(void)          //根据按键消息队列信息实时处理
{  static uint8  i=0;
   uint8  j; //  修改为static   uint8  j ;   

OSQCreate(Command1602Buf,8);        //建立1602命令消息队列
   //OSWait(K_TMO,100);


//

使用特权

评论回复
28
刘前辈| | 2011-3-31 18:43 | 只看该作者
很简单的证实调试,把写6个空格" " 缩小改成写一个,二个;什么效果?


case(CLR_ALLSTAR):  //删除所有星号,问题就出在这了。只要按下这个键一会就出问题了
    addr=9;
       Write_string(2,10," ");

使用特权

评论回复
29
刘前辈| | 2011-3-31 20:05 | 只看该作者
在函数前面加"#pragma  disable ";这么严格的时序还不保护?

#pragma  disable
void Write_Date(uint8 c)                   //写数据函数
{
  //OS_ENTER_CRITICAL();
  Datecom=c;
  RW=0;
  RS=1;
  E=0;
  delay();
  E=1;
  delay();
  //OS_EXIT_CRITICAL();
}



/

使用特权

评论回复
30
zhouwenbin1989|  楼主 | 2011-3-31 22:03 | 只看该作者
28# 刘前辈


写一个结果好像也一样,现在我开始有点怀疑硬件了,等我拿硬件检修回来后再试下

使用特权

评论回复
31
刘前辈| | 2011-4-1 19:12 | 只看该作者
   OSWait(K_SIG,0); //前面关中断到这句话后面才打开,中断都关了,那定时器怎么能唤起任务。??????


这里是睡眠等待另一个任务的唤醒信号K_SIG,和定时器没有关系。从这里开始,当前任务睡眠,调度器触发切换到其它就绪任务了。


、、

使用特权

评论回复
32
刘前辈| | 2011-4-1 19:14 | 只看该作者
顶你的签名!

在路上。人的一生很短,但是如果卑劣的过这一生,那么很长。


、、

使用特权

评论回复
33
zhouwenbin1989|  楼主 | 2011-4-1 23:08 | 只看该作者
31# 刘前辈


这里我懂了,他是不同的任务保存不同的关中断状态。想问下前辈你是学什么的,计算机的还是电子,感觉你对系统的领悟很好啊

使用特权

评论回复
34
刘前辈| | 2011-4-2 09:40 | 只看该作者
本帖最后由 刘前辈 于 2011-4-2 09:57 编辑
这里我懂了,他是不同的任务保存不同的关中断状态



不同意上面:举例:如果一个任务A由于某种原因关闭了中断,然后睡眠,那么以后谁来打开中断?  
    所以,一个关闭了中断的任务A,必须执行到自愿放弃点,直到恢复中断正常工作状态,才能结束自己当前运行态(去睡眠或其他),交出CPU控制权,——“谁关断的中断,谁负责打开。”即使时间片超时,也不可能截止任务A的未执行完状态(本来就不可能,因为中断已经关闭,调度不可能被触发。)如果由于程序员的疏忽,使任务A恢复中断,那系统就死了。

    所以,OS有更高级的处理机制,无需程序员管理,而由OS管理临界区,例如HOAR的管程机制,条件变量什么的。——有需求就总有人研究。

     

使用特权

评论回复
35
刘前辈| | 2011-4-2 10:04 | 只看该作者
本帖最后由 刘前辈 于 2011-4-2 10:06 编辑

还有下面这里调试发现问题很容易:你说去掉11号功能,一切正常。
         那么好办,把下面红色注释掉,看看什么结果,——按道理应该像10号功能一样正常。
         马上就能找到问题所在了。

else if(Keytemp[0]==0x0b)        //按下11号按键即删除全部“*”.问题就出在这。
         {
             //   for(j=0;j<6;j++)
                Password[j]=0;
         // 这句注释掉。
                //delay1();
                OSQPost(Command1602Buf,CLR_ALLSTAR);
         }

使用特权

评论回复
36
zhouwenbin1989|  楼主 | 2011-4-2 12:53 | 只看该作者
[quote]


不同意上面:举例:如果一个任务A由于某种原因关闭了中断,然后睡眠,那么以后谁来打开中断?  
  
这里是这样的(我的理解):
A睡眠后,系统切换到就绪优先级最高的任务执行(假设是任务B),在切换的时候会判断B上次睡眠时关中断计数器(ENTER_SUM)的值,如果B睡眠时B是关中断的话切换过去还是关中断,但是如果B的关中断是打开的的话切换过去时会在内核函数中自动打开中断。

使用特权

评论回复
37
zhouwenbin1989|  楼主 | 2011-4-2 13:01 | 只看该作者
36# 刘前辈


这种方法试过了,没什么改变。

使用特权

评论回复
38
zhouwenbin1989|  楼主 | 2011-4-2 13:14 | 只看该作者
36# 刘前辈



我的感觉是我在任务的循环中,对一个要处理较长时间的操作没处理好(而这里这个操作就是在1602中写字符串)。影响后面的系统正常运行。可是我现在还是没想好该怎么处理这个操作才合理。

使用特权

评论回复
39
zhouwenbin1989|  楼主 | 2011-4-2 13:25 | 只看该作者
12# ayb_ice

TINY不是时间片轮询吗?

使用特权

评论回复
40
zhouwenbin1989|  楼主 | 2011-4-2 13:42 | 只看该作者
36# 刘前辈


我的问题搞定了,原来是在KeyHandle(void)函数中,当按下删除全部是我没有将静态变量i置0,导致后面出错。谢谢你这几天给我提供的帮助,太感谢了。以后希望能有跟多机会互相学习

使用特权

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

本版积分规则