os_time.c

  定位到uCOS-II/Source/os_time.c,该文件是系统时间相关。

  由于嵌入式系统的任务是一个无限循环,而uCOS-II是一个抢占式内核,所以为了能让高优先级的任务不一直独占CPU,应该适当的让出CPU以给其他优先级较低的任务获得CPU得以执行。所谓“让出”即使任务进入延时,在延时期间让出CPU。

1. 延时函数OSTimeDly()

void  OSTimeDly (INT32U ticks)
{
    INT8U      y;
#if OS_CRITICAL_METHOD == 3u    /* 临界区保护,需要使用变量cpu_sr */
    OS_CPU_SR  cpu_sr = 0u;
#endif

    if (OSIntNesting > 0u) {    /* OSIntNesting为中断嵌套的层数,表示是在某个ISR调用的 */
        return;
    }
    if (OSLockNesting > 0u) {   /* 加锁时OSLockNesting会大于0 */
        return;
    }
    if (ticks > 0u) {           /* 大于0才是有效延时 */
        OS_ENTER_CRITICAL();
        y            =  OSTCBCur->OSTCBY;   /* 将当前任务在任务就绪表中标志位非就绪态,让出CPU */
        OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;
        if (OSRdyTbl[y] == 0u) {
            OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;
        }
        OSTCBCur->OSTCBDly = ticks; /* 延时节拍数存入当前任务的TCB */
        OS_EXIT_CRITICAL();         /* 退出临界区 */
        OS_Sched();                 /* 当前任务已经处于挂起态,调度后轮到次于当前优先级的就绪任务执行 */
    }
}

  函数的参数ticks是以系统节拍数为单位的延时时间设置值,延时期间会让出CPU供其他任务使用。一般我们设置硬件tick为10ms产生一次sysytick中断,所以此函数存在缺陷:不能延时小于10ms且延时的时间需是10ms的整数倍。

2. 延时函数OSTimeDlyHMSM()

#if OS_TIME_DLY_HMSM_EN > 0u
INT8U  OSTimeDlyHMSM (INT8U   hours,
                      INT8U   minutes,
                      INT8U   seconds,
                      INT16U  ms)
{
    INT32U ticks;
    if (OSIntNesting > 0u) {         
        return (OS_ERR_TIME_DLY_ISR);
    }
    if (OSLockNesting > 0u) {
        return (OS_ERR_SCHED_LOCKED);
    }
#if OS_ARG_CHK_EN > 0u      //OS_ARG_CHK_EN为参数检查宏
    //hours、minutes、seconds、ms都为0那就不要延时了
    if (hours == 0u) {
        if (minutes == 0u) {
            if (seconds == 0u) {
                if (ms == 0u) {
                    return (OS_ERR_TIME_ZERO_DLY);
                }
            }
        }
    }
    //参数合法检查
    if (minutes > 59u) {
        return (OS_ERR_TIME_INVALID_MINUTES);  
    }
    if (seconds > 59u) {
        return (OS_ERR_TIME_INVALID_SECONDS);
    }
    if (ms > 999u) {
        return (OS_ERR_TIME_INVALID_MS);
    }
#endif

    /* 根据输入参数,四舍五入推算tick数 */
    ticks = ((INT32U)hours * 3600uL + (INT32U)minutes * 60uL + (INT32U)seconds) * OS_TICKS_PER_SEC
          + OS_TICKS_PER_SEC * ((INT32U)ms + 500uL / OS_TICKS_PER_SEC) / 1000uL;

    /* 调用上面的延时函数OSTimeDly() */
    OSTimeDly(ticks);
    return (OS_ERR_NONE);
}
#endif

  为了能使用日常习惯的方法来使任务延时,uCOS-II还提供了OSTimeDlyHMSM函数,该函数可以指定时分秒、毫秒进行延时。其中OS_TICKS_PER_SEC变量指明每秒钟发生几次systick,1ms产生一次systick,那么1秒就是1000次。

3. 中止任务继续延时函数OSTimeDlyResume()

#if OS_TIME_DLY_RESUME_EN > 0u
INT8U  OSTimeDlyResume (INT8U prio)
{
    OS_TCB    *ptcb;
#if OS_CRITICAL_METHOD == 3u 
    OS_CPU_SR  cpu_sr = 0u;
#endif

    if (prio >= OS_LOWEST_PRIO) {       //参数合法性判断
        return (OS_ERR_PRIO_INVALID);
    }
    OS_ENTER_CRITICAL();                //进入临界区
    ptcb = OSTCBPrioTbl[prio];          //从就绪表中取出任务的TCB

    if (ptcb == (OS_TCB *)0) {          //为NULL表就绪表中没有此任务
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_NOT_EXIST); 
    }
    if (ptcb == OS_TCB_RESERVED) {      //为OS_TCB_RESERVED表该不存在该任务,任务块ptcb被其他任务占用
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_NOT_EXIST); 
    }
    if (ptcb->OSTCBDly == 0u) {         //为0表示不延时
        OS_EXIT_CRITICAL();
        return (OS_ERR_TIME_NOT_DLY);   
    }

    ptcb->OSTCBDly = 0u;   /* OSTCBDly被赋值为0,表不再延时 */

    //阻塞和挂起的判断:
    if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {              
    //判断是否是因为等待某事件的到来而延时,不等则说明是
        ptcb->OSTCBStat     &= ~OS_STAT_PEND_ANY;              /* 清除挂起标志 */
        ptcb->OSTCBStatPend  =  OS_STAT_PEND_TO;               /* 指示不再等待的原因是因为超时  */
    } else {                                                   // 延时调用延时函数而引起的
        ptcb->OSTCBStatPend  =  OS_STAT_PEND_OK;               // 结束等待的原因是等待结束了
    }

    /* 若任务不是被阻塞,而是挂起状态,设置该任务在就绪表中设置为就绪状态 */
    if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {  /* Is task suspended?                   */
        OSRdyGrp               |= ptcb->OSTCBBitY;             /* No,  Make ready                      */
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        OS_EXIT_CRITICAL();
        OS_Sched();                                            /* See if this is new highest priority  */
    } else {
        OS_EXIT_CRITICAL();                                    /* Task may be suspended                */
    }
    return (OS_ERR_NONE);
}
#endif

  任务调用了OSTimeDly()/OSTimeDlyHMSM()函数,当规定的延时时间超时,或者其他任务调用OSTimeDlyResume()取消其延时,该任务就会进入就绪状态。参数prio用于指定被取消延时的任务的优先级。

  在这里,总结PEND和SUSPEND状态的差别:
  (1) PEND为阻塞之意,任务在PEND过程中会释放CPU资源,其它任务可以得到执行。PEND一般在等待某个事件的出现。SUSPEND为暂停、挂起之意,任务在SUSPEND过程中不释放CPU资源。一般挂起用于程序调试中的条件中断,即出现某个条件的情况下挂起,然后进行单步调试。

  (2) 挂起是一种主动行为,因此恢复也应该主动完成。阻塞是一种被动行为,被阻塞的任务不知道自己什么时候被挂起了,也不知道什么时候能恢复。

  (3) PEND和NOTPEND/PEND_OK/PEND_TO对应

  (4) SUSPEND和RDY对应

4. 读取时间函数OSTimeGet()

#if OS_TIME_GET_SET_EN > 0
INT32U  OSTimeGet (void)
{
    INT32U     ticks;
#if OS_CRITICAL_METHOD == 3  
    OS_CPU_SR  cpu_sr = 0;
#endif

    OS_ENTER_CRITICAL();
    ticks = OSTime;
    OS_EXIT_CRITICAL();
    return (ticks);
}
#endif

  为了方便,系统定义了一个INT32U类型的全局变量OSTime来记录系统发生的时钟节拍数。OSTime在应用程序中调用的OSStart()时被初始化为0,之后每发生一个时钟节拍,OSTime的值就会被加1。OSTimeGet()的返回OSTimeGet的值。

5. 设置时间函数OSTimeSet()

#if OS_TIME_GET_SET_EN > 0
void  OSTimeSet (INT32U ticks)
{
#if OS_CRITICAL_METHOD == 3
    OS_CPU_SR  cpu_sr = 0;
#endif
    OS_ENTER_CRITICAL();
    OSTime = ticks;
    OS_EXIT_CRITICAL();
}
#endif

  OSTimeSet()用于设置OSTime的值。

  这5个函数还是比较简单,都是c语言基础,个人觉得关键主要还是在PEND和SUSPEND的理解。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用QTimer对象代替QBasicTimer对象,修改程序class MyWindow(QWidget): def init(self): super().init() self.thread_list = [] self.color_photo_dir = os.path.join(os.getcwd(), "color_photos") self.depth_photo_dir = os.path.join(os.getcwd(), "depth_photos") self.image_thread = None self.saved_color_photos = 0 # 定义 saved_color_photos 属性 self.saved_depth_photos = 0 # 定义 saved_depth_photos 属性 self.init_ui() def init_ui(self): self.ui = uic.loadUi("C:/Users/wyt/Desktop/D405界面/intelrealsense1.ui") self.open_btn = self.ui.pushButton self.color_image_chose_btn = self.ui.pushButton_3 self.depth_image_chose_btn = self.ui.pushButton_4 self.open_btn.clicked.connect(self.open) self.color_image_chose_btn.clicked.connect(lambda: self.chose_dir(self.ui.lineEdit, "color")) self.depth_image_chose_btn.clicked.connect(lambda: self.chose_dir(self.ui.lineEdit_2, "depth")) def open(self): self.profile = self.pipeline.start(self.config) self.is_camera_opened = True self.label.setText('相机已打开') self.label.setStyleSheet('color:green') self.open_btn.setEnabled(False) self.close_btn.setEnabled(True) self.image_thread = ImageThread(self.pipeline, self.color_label, self.depth_label, self.interval, self.color_photo_dir, self.depth_photo_dir, self._dgl) self.image_thread.saved_color_photos_signal.connect(self.update_saved_color_photos_label) self.image_thread.saved_depth_photos_signal.connect(self.update_saved_depth_photos_label) self.image_thread.start() def chose_dir(self, line_edit, button_type): my_thread = MyThread(line_edit, button_type) my_thread.finished_signal.connect(self.update_line_edit) self.thread_list.append(my_thread) my_thread.start()
最新发布
05-26

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值