资讯动态

Flipper Zero 倒计时定时器应用(Count Down Timer)完整使用与源码解析

发布时间:2026/9/13 15:27:22 来源:尧图企业网站定制
Flipper Zero 倒计时定时器应用Count Down Timer完整使用与源码解析【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper本文围绕 Flipper Zero 开源仓库中的 Count Down Timer 倒计时定时器应用完整讲解其按键操作逻辑、时间设置机制、运行状态机与底层实现原理。文章以 Applications/Official/source-OLDER/grnch/cntdown_timer/README.md 为主线并结合 countdown_view.c、app.c 等源码深入解析其内部工作方式读完你既能熟练操作该应用也能理解一个典型的 Flipper Zero 外部 FAP 应用是如何组织与运行的。应用概述Count Down Timer 是一个运行在 Flipper Zero 上的简单倒计时定时器应用。它通过 Flipper Zero 的 128x64 单色屏幕以HH:MM:SS格式实时显示剩余时间并在倒计时结束时触发声音与屏幕闪烁的视听告警。该应用属于官方固件外部应用EXTERNAL FAP源码位于仓库 Applications/Official/source-OLDER/grnch/cntdown_timer 目录由 Applications/Official/source-OLDER/README.md 中说明的 grnch / kyhwana 提供的编译源码归档而来。从构建清单 application.fam 可以看到应用的元信息字段值说明appidCount_Down_Timer应用唯一标识nameCount Down Timer显示名称apptypeFlipperAppType.EXTERNAL外部 FAP 应用entry_pointapp_main入口函数requires[gui]依赖 GUI 子系统stack_size2 * 1024应用线程栈大小order20菜单排序fap_iconcntdown_timer.png应用图标fap_categoryTools菜单分类Tools 工具类按键操作指南原文档给出了完整按键映射结合源码 countdown_view.c 的输入回调可确认全部行为按键操作源码对应逻辑left/right在「秒 / 分 / 时」三个调节位之间切换选中项handle_time_setting_select中通过selection (selection ± 1) % 3循环切换up/down增加 / 减小当前选中位的值秒位每次 ±1分位每次 ±60时位每次 ±3600ok短按开始 / 暂停倒计时CountDownTimerToggleCounting切换运行状态ok长按停止计时并重置为设置值CountDownTimerReset停止定时器、复位计数back长按退出应用返回false交由视图调度器退出需要注意的操作细节选中位有视觉反馈屏幕中央大号数字FontBigNumbers下方会绘制一条下划线标记当前选中的调节位对应draw_selection函数中的elements_slightly_rounded_box绘制逻辑countdown_view.c。计时中无法修改时间handle_time_setting_select开头会检查counting标志倒计时运行期间up/down/left/right输入一律被忽略countdown_view.c。数字只能减到 0任何使计数变为负数的操作都会被钳制为 0if(count 0) count 0;。应用启动默认值为 10 秒INIT_COUNT宏定义为 10countdown_view.h进入视图时count与saved_count_setting均被初始化为该值countdown_view.c。时间设置与显示原理三档调节机制应用将时间拆分为秒、分、时三个调节位内部用CountDownViewSelect枚举表示typedef enum { CountDownTimerSelectSec, CountDownTimerSelectMinute, CountDownTimerSelectHour, } CountDownViewSelect;left/right按键使selection在三个值之间以模 3 方式循环左移selection--右移selection。up/down则根据当前选中位换算为对应的秒数步进统一累加到model-count中秒位count 1/count - 1分位count 60/count - 60时位count 3600/count - 3600每次调整后model-count和model-saved_count_setting会被同步更新countdown_view.c。saved_count_setting保存的是设置的目标时间它在倒计时过程中保持不变并在重置时恢复。时间字符串格式化显示时使用工具函数parse_sec_to_time_str将秒数转换为HH:MM:SS字符串utils/utils.cvoid parse_sec_to_time_str(char* buffer, size_t len, int32_t sec) { snprintf( buffer, len, %02ld:%02ld:%02ld, (sec % (60 * 60 * 24)) / (60 * 60), // hour (sec % (60 * 60)) / 60, // minute sec % 60); // second }格式化结果通过canvas_draw_str_aligned以屏幕中心SCREEN_CENTER_X64、SCREEN_CENTER_Y32为基准居中绘制并配合elements_progress_bar在屏幕顶部绘制一条进度条其填充比例由count / expected_count计算得出直观反映剩余时间占比countdown_view.c。屏幕尺寸常量定义在 countdown_view.h 中SCREEN_WIDTH 128、SCREEN_HEIGHT 64。倒计时运行状态机开始、暂停与重置运行状态由CountDownTimView结构体中的counting布尔标志与一个 1 Hz 周期的FuriTimer定时器共同驱动开始 / 暂停短按ok触发countdown_timer_state_toggle在countdown_timer_start_countingfuri_timer_start周期为furi_kernel_get_tick_frequency() * 1即 1 秒与countdown_timer_pause_countingfuri_timer_stop之间切换countdown_view.c。重置长按ok触发CountDownTimerReset依次执行furi_timer_stop、countdown_timer_view_state_reset和notification_off。其中countdown_timer_view_state_reset将counting置为false并把model-count恢复为model-saved_count_settingcountdown_view.c。每秒递减与到时告警定时器回调timer_cb是倒计时的核心引擎countdown_view.c通过with_view_model加锁读取并递减model-count若count 0钳制为 0 并置timeup标志若到时调用handle_misc_cmd(cdv, CountDownTimerTimeUp)最终触发notification_timeup()。notification_timeup通过RECORD_NOTIFICATION记录发送sequence_audiovisual_alert预设序列utils/utils.c产生声音与屏幕闪烁的视听提醒。工具模块还提供了自定义的单次蜂鸣序列sequence_beep蓝色 LED D5 音符 100ms 延时以及配套的notification_beep_once、notification_off辅助函数便于开发者扩展提示方式utils/utils.c。应用框架视图调度器与生命周期Count Down Timer 也展示了 Flipper Zero 外部应用的标准工程组织方式整个工程由三个模块构成cntdown_timer/ ├── app.c / app.h # 应用入口与生命周期管理 ├── application.fam # FAP 构建清单 ├── cntdown_timer.png # 应用图标 ├── views/ │ ├── countdown_view.c / .h # 倒计时视图绘制、输入、定时器 └── utils/ ├── utils.c / utils.h # 时间格式化与通知工具入口与生命周期app_main是构建清单entry_point指定的入口函数采用标准的新建 → 运行 → 删除三段式生命周期app.cint32_t app_main(void* p) { UNUSED(p); CountDownTimerApp* app countdown_app_new(); countdown_app_run(app); countdown_app_delete(app); return 0; }countdown_app_new完成 GUI 子系统连接与视图调度器初始化app.cfuri_record_open(RECORD_GUI)打开 GUI 记录view_dispatcher_alloc()分配视图调度器并启用事件队列view_dispatcher_attach_to_gui(..., ViewDispatcherTypeFullscreen)以全屏模式挂载到 GUI创建倒计时视图以0xff为 view id 注册并设置退出回调view_exit返回VIEW_NONEview_dispatcher_switch_to_view(dispatcher, 0xff)切换到默认视图。countdown_app_delete则逆序释放视图、视图调度器、关闭 GUI 记录并释放应用内存app.c。视图内部的定时器也在countdown_timer_view_delete中通过furi_timer_stop/furi_timer_free妥善清理countdown_view.c。视图模型与线程安全值得开发者借鉴的是其线程安全设计应用使用view_allocate_model(view, ViewModelTypeLocking, sizeof(CountDownModel))分配带锁的视图模型countdown_view.c。所有对CountDownModel的读写无论是输入回调还是定时器回调都通过with_view_model宏进行确保 UI 线程与定时器线程之间访问数据不会产生竞争条件。模型结构定义于 countdown_view.htypedef struct { int32_t count; // 当前剩余秒数 int32_t saved_count_setting; // 设置的目标秒数重置时恢复 CountDownViewSelect select; // 当前选中的调节位 } CountDownModel;构建与安装Count Down Timer 属于FlipperAppType.EXTERNAL外部应用需要针对所使用的固件版本单独编译为.fap文件。在 Flipper Zero 固件开发环境中使用fbtFlipper Build Tool执行./fbt fap_dist即可编译仓库中的全部 FAP 应用仅编译本应用可使用./fbt fap_Count_Down_Timer。编译产物.fap文件放入 SD 卡的apps目录后从 Flipper Zero 的 Applications 菜单中即可找到并运行。需要注意FAP 文件与固件 API 存在版本绑定关系不同固件如官方固件与定制固件之间的.fap文件通常不能互换具体说明可参考仓库 Applications/ReadMe.md。扩展思路从源码结构看该应用具备清晰的扩展空间修改默认时间调整 countdown_view.h 中的INIT_COUNT宏即可改变应用启动时的默认倒计时时长。自定义提示音在 utils/utils.c 中修改sequence_beep序列LED 颜色、音符、时长即可定制单次蜂鸣效果notification_timeup目前使用固件预设的sequence_audiovisual_alert也可替换为自定义序列。调整定时精度countdown_timer_start_counting中定时周期furi_kernel_get_tick_frequency() * 1对应 1 秒改为其他系数即可实现更细粒度的倒计时。本文所述内容均可在仓库 Applications/Official/source-OLDER/grnch/cntdown_timer 目录下找到对应源码进行验证读者可结合源码进一步探索 Flipper Zero 外部应用的开发模式。【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价