MacOS环境-手写操作系统-26-利用时钟开发光标闪烁

简介: MacOS环境-手写操作系统-26-利用时钟开发光标闪烁

利用时钟开发光标闪烁

1.简介

上一节,我们已经实现了时钟超时功能 但一个操作系统 肯定是能支持多个时钟的


本节 我们就看看如何从上一节的单时钟向多时钟转变 同时利用时钟超时机制实现光标的闪烁特效


2.代码

现在 我们要把有个时钟的信息抽取出来


这样的话 就使得一个控制器能对应管理很多个时钟对象


因此我们改动timer.h

#define PIT_CTRL   0x0043
#define PIT_CNT0   0x0040

#define MAX_TIMER  500

void init_pit(void);

struct TIMER {
    unsigned int timeout, flags;
    struct FIFO8 *fifo;
    unsigned char data;
};

struct TIMERCTL {
    unsigned int count;

    struct TIMER timer[MAX_TIMER];

};

struct TIMER* timer_alloc(void);

void timer_free(struct TIMER *timer);

void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data) ;

void timer_settime(struct TIMER *timer, unsigned int timeout);

大家看到 原来在TIMERCTL中的一些信息已经抽取出来 独立成为一个TIMER对象


而在控制器里包含的是一组TIMER数组 这样 一个控制器就能对应很多个时钟对象了


timer_alloc用来分配一个TIMER对象 一个TIMER对象被分配出来后 需要用timer_init初始化


然后使用timer_settime设置时间片


相关函数的时间 在timer.c中

struct TIMER* timer_alloc(void) {
    int i;
    for (i = 0; i < MAX_TIMER; i++) {
        if (timerctl.timer[i].flags == 0) {
            timerctl.timer[i].flags = TIMER_FLAGS_ALLOC;
            return &timerctl.timer[i];
        }
    }

    return 0;
}

void timer_free(struct TIMER *timer) {
    timer->flags = 0;
    return;
}

void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data) {
    timer->fifo = fifo;
    timer->data = data;
    return;
}

void timer_settime(struct TIMER *timer, unsigned int timeout) {
    timer->timeout = timeout;
    timer->flags = TIMER_FLAGS_USING;
    return;
}

TIMER对象的分配 其实就是从时钟控制器的TIMER数组中找到一个还没有被使用的对象


将其它的状态从free 转换为alloc


也就是表明当前时钟对象已经被占用 然后从数组中直接返回时钟对象


timer_settime 就是把时间片信息设置到对应的TIMER对象而已


需要注意的是intHandlerForTimer函数的更改

void intHandlerForTimer(char *esp) {
    io_out8(PIC0_OCW2, 0x60);
    timerctl.count++;

    int i;
    for (i = 0; i < MAX_TIMER; i++) {
        if (timerctl.timer[i].flags == TIMER_FLAGS_USING) {
            timerctl.timer[i].timeout--;
            if (timerctl.timer[i].timeout == 0) {
                timerctl.timer[i].flags = TIMER_FLAGS_ALLOC;
                fifo8_put(timerctl.timer[i].fifo, timerctl.timer[i].data);
            }
        }
    }

    return;
}

每次时钟中断发生时


我们的中断处理函数会变量时钟控制器中的时钟数组 把数组中时钟对象的时间片减一


如果有哪个时钟的时间片已经消耗完毕 那么就往对应时钟的数据队列里写入一个数据


用于通知内核触发对应的超时操作


有了多时钟功能后 内核就可以利用该机制


创建多个时钟 然后响应多个超时事件了


内核的改动如下 write_vga_desktop.c

void CMain(void) {
   .....
struct TIMER *timer, *timer2, *timer3;
    static struct FIFO8 timerfifo2, timerfifo3;
    static char timerbuf2[8], timerbuf3[8];

    init_pit();
    fifo8_init(&timerinfo, 8, timerbuf);
    timer = timer_alloc();
    timer_init(timer, &timerinfo, 1);
    timer_settime(timer, 500);

    fifo8_init(&timerfifo2, 8, timerbuf2);
    timer2 = timer_alloc();
    timer_init(timer2, &timerfifo2, 1);
    timer_settime(timer2, 300);

    fifo8_init(&timerfifo3, 8, timerbuf3);
    timer3 = timer_alloc();
    timer_init(timer3, &timerfifo3, 1);
    timer_settime(timer3, 50);
   ....
}

我们看到 内核入口函数申请了三个时钟对象 并将他们初始化

第一个时钟的时间片是5秒

第二个时钟的时间片是3秒

第三个时钟的时间片是0.5秒

有了三个时钟 我们就需要对三个时钟的超时做不同处理

继续看代码

void CMain(void) {
   .....

for(;;) {
       char* pStr = intToHexStr(timer->timeout);
       boxfill8(shtMsgBox->buf, 160, COL8_C6C6C6, 40, 28, 119, 43);
       showString(shtctl, shtMsgBox, 40, 28, COL8_000000,pStr);

       io_cli();
       if (fifo8_status(&keyinfo) + fifo8_status(&mouseinfo) +
           fifo8_status(&timerinfo) + fifo8_status(&timerfifo2) 
           + fifo8_status(&timerfifo3) == 0) {

           io_sti();
       }
       ....
       else if (fifo8_status(&timerinfo) != 0) {
           io_sti();
           fifo8_get(&timerinfo);
           showString(shtctl, sht_back, 0, 0, COL8_FFFFFF, " new 5[sec]");
       } else if (fifo8_status(&timerfifo2) != 0) {
           fifo8_get(&timerfifo2);
           io_sti();
           showString(shtctl, sht_back, 0, 16, COL8_FFFFFF, "3[sec]");
       }else if (fifo8_status(&timerfifo3) != 0) {
           int i = fifo8_get(&timerfifo3);
           io_sti();
           if (i != 0) {
              timer_init(timer3, &timerfifo3, 0);
              boxfill8(buf_back, xsize, COL8_FFFFFF, 8, 96, 15, 111);
           } else {
              timer_init(timer3, &timerfifo3, 1);
              boxfill8(buf_back, xsize, COL8_008484, 8, 96, 15, 111);
           }

           timer_settime(timer3, 50);
           sheet_refresh(shtctl, sht_back, 8, 96, 16, 112);
       }
   ....   
}

第一个时钟超时时


我们还是在桌面左上角显示一个字符串


第二个时钟超时时


我们也同样在左上角显示一个字符串


第三个时钟的处理 需要我们注意 在初始化第三个时钟是 我们会传入一个数值 也就是上一节描述的时钟data


当超时后 这个数值会被放入回时钟对应的队列里面 那么我们可以根据这个值采取不同的动作去处理超时


如果第三个时钟超时了 同时在队列里面的数值不等于0


那么我们就在桌面上画一个白色的小方块然后再次初始化该时钟 并把数值0传进去


下次时钟再超时 那么内核得到的数值就是0 于是内核把上次绘制的小方块给擦掉


这样的话 就形成一个效果 就是一个白色小方块在桌面上闪来闪去 就好像一个光标一样


3.编译运行


目录
相关文章
|
17天前
|
存储 人工智能 JavaScript
Harmony OS开发-ArkTS三
本文介绍了ArkTS的基础语法,包括常量、命名规则、数组及其常用函数,以及函数的定义与使用,涵盖匿名函数和箭头函数的区别。通过具体示例,帮助读者快速掌握ArkTS编程技巧,踏上Harmony OS开发之旅。君志所向,一往无前!
36 1
Harmony OS开发-ArkTS三
|
4月前
|
安全 搜索推荐 Android开发
移动应用与系统:探索开发趋势与操作系统优化策略####
当今数字化时代,移动应用已成为日常生活不可或缺的一部分,而移动操作系统则是支撑这些应用运行的基石。本文旨在探讨当前移动应用开发的最新趋势,分析主流移动操作系统的特点及优化策略,为开发者提供有价值的参考。通过深入剖析技术创新、市场动态与用户需求变化,本文力求揭示移动应用与系统协同发展的内在逻辑,助力行业持续进步。 ####
78 9
|
20天前
|
存储 人工智能 编译器
【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
43 10
【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
|
16天前
|
前端开发 JavaScript 开发工具
【04】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-正确安装鸿蒙SDK-结构目录介绍-路由介绍-帧动画(ohos.animator)书写介绍-能够正常使用依赖库等-ArkUI基础组件介绍-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
【04】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-正确安装鸿蒙SDK-结构目录介绍-路由介绍-帧动画(ohos.animator)书写介绍-能够正常使用依赖库等-ArkUI基础组件介绍-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
91 5
【04】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-正确安装鸿蒙SDK-结构目录介绍-路由介绍-帧动画(ohos.animator)书写介绍-能够正常使用依赖库等-ArkUI基础组件介绍-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
|
20天前
|
JavaScript 编译器 开发工具
【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
56 2
【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
|
23天前
|
安全 前端开发 开发工具
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
60 5
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
|
2月前
|
存储 人工智能 JavaScript
Harmony OS开发-ArkTS语言速成二
本文介绍了ArkTS基础语法,包括三种基本数据类型(string、number、boolean)和变量的使用。重点讲解了let、const和var的区别,涵盖作用域、变量提升、重新赋值及初始化等方面。期待与你共同进步!
135 47
Harmony OS开发-ArkTS语言速成二
|
10天前
|
Android开发 UED iOS开发
Harmony os next~UI开发与ArkUI框架
鸿蒙OS的UI开发基于ArkUI框架,采用声明式编程,简化开发流程。五大核心组件(Text、Button、List、Grid、Flex)助力高效布局,支持数据绑定与动态更新。事件响应机制灵敏,适合构建交互丰富的应用。实战技巧包括规范命名、样式复用和调试方法。掌握这些,轻松开发鸿蒙应用。下期预告:分布式开发,记得带上烤冷面!
24 0
|
10天前
|
XML 存储 大数据
Harmony os next~HarmonyOS Ability与页面跳转开发详解
HarmonyOS采用分布式架构,其Ability体系包括Page、Service、Data和Form四大类型Ability。Page Ability支持多页面跳转与数据传递,Service Ability用于后台任务,Data Ability提供数据共享接口,Form Ability实现轻量化卡片服务。本文详细解析了各Ability的开发方法、生命周期管理、跨Ability通信及最佳实践,帮助开发者掌握HarmonyOS应用开发的核心技能。
59 0
|
3月前
|
开发框架 JavaScript 前端开发
Harmony OS开发-ArkT语言速成一
本文介绍ArkTS语言,它是鸿蒙生态的应用开发语言,基于TypeScript,具有静态类型检查、声明式UI、组件化架构、响应式编程等特性,支持跨平台开发和高效性能优化。ArkTS通过强化静态检查和分析,提升代码健壮性和运行性能,适用于Web、移动端和桌面端应用开发。关注我,带你轻松掌握HarmonyOS开发。
92 5
Harmony OS开发-ArkT语言速成一

热门文章

最新文章