0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

不依賴硬件,可以無(wú)限擴(kuò)展的鬧鐘組件

Rice嵌入式開發(fā)技術(shù)分享 ? 來(lái)源:Rice 嵌入式開發(fā)技術(shù)分享 ? 作者:Rice 嵌入式開發(fā)技 ? 2023-05-18 08:40 ? 次閱讀
  1. 在實(shí)際的開發(fā)項(xiàng)目中,很多時(shí)候我們需要定時(shí)的做一些事情,舉例:

  • ①路上的路燈,每天晚上6:00準(zhǔn)時(shí)打開,每天早上6:00準(zhǔn)時(shí)關(guān)閉;
  • ②定時(shí)鬧鐘,起床上班。這些行為其實(shí)都是定時(shí)任務(wù)--鬧鐘。
  • 大部分單片機(jī)都提供了rtc alarm硬件鬧鐘,但是實(shí)際很少人使用,就舉個(gè)簡(jiǎn)單的例子,rt-thread的BSP中也沒有幾個(gè)芯片適配了alarm硬件鬧鐘。但是我們要使用怎么辦??

  • 我受到RTOS的調(diào)度的啟發(fā),像M3/M4這種內(nèi)核都是SysTick產(chǎn)生時(shí)鐘節(jié)拍,以供系統(tǒng)處理所有和時(shí)間有關(guān)的事情,如線程延時(shí),線程的時(shí)間片輪轉(zhuǎn),以及定時(shí)器超時(shí)等。

  • 有了第3點(diǎn)的經(jīng)驗(yàn),那么我們可以寫一個(gè)軟件鬧鐘功能就容易多了,只需要提供一個(gè)刷新節(jié)拍,定時(shí)查看哪一個(gè)鬧鐘需要喚醒,就可以解決鬧鐘的管理了。

  • 鬧鐘組件名字:RAlarm(全稱Rice Alarm),源碼連接:https://gitee.com/RiceChen0/ralarm

RAlarm

RAlarm接口說明:

跨平臺(tái)

  • RTOS的種類很多,接口差異性打,所以RAlarm為了解決這個(gè)問題,統(tǒng)一為上層提供一整套接口。
  1. 線程接口。
typedefvoid*ralarm_task_id;

structralarm_task_attr{
constchar*name;//nameofthetask
uint32_tstack_size;//sizeofstack
uint8_tpriority;//initialtaskpriority
};

typedefvoid(*ralarm_task_func)(void*arg);

ralarm_task_idralarm_task_create(ralarm_task_funcfunc,void*arg,conststructralarm_task_attr*attr);
voidralarm_task_delete(ralarm_task_idthread);
  1. 互斥量接口。
typedefvoid*ralarm_mutex_id;

ralarm_mutex_idralarm_mutex_create(void);
ralarm_err_tralarm_mutex_lock(ralarm_mutex_idmutex);
ralarm_err_tralarm_mutex_unlock(ralarm_mutex_idmutex);
voidralarm_mutex_delete(ralarm_mutex_idmutex);
  1. 事件接口。
typedefvoid*ralarm_event_id;

ralarm_event_idralarm_event_create(void);
uint32_tralarm_event_recv(ralarm_event_idevent,uint32_tflags);
ralarm_err_tralarm_event_send(ralarm_event_idevent,uint32_tflags);
voidralarm_event_delete(ralarm_event_idevent);
  • RAlarm目前已經(jīng)提供了兩個(gè)環(huán)境的適配,如cmsis,rtthread。

接口使用簡(jiǎn)單

接口 說明
ralarm_init 初始化
ralarm_deinit 去初始化
ralarm_create 創(chuàng)建鬧鐘
ralarm_start 啟動(dòng)鬧鐘
ralarm_stop 停止鬧鐘
ralarm_modify 修改鬧鐘
ralarm_delete 刪除鬧鐘
  • 鬧鐘初始化接口:初始化鬧鐘的鏈表,鬧鐘任務(wù),事件,互斥鎖;去初始化接口:注銷鬧鐘組件
/*鬧鐘初始化*/
ralarm_err_tralarm_init(void);

/*鬧鐘去初始化*/
voidralarm_deinit(void);
  • 鬧鐘創(chuàng)建:
  1. 參數(shù)說明:
「參數(shù)」 「描述」
setup 鬧鐘的時(shí)間和標(biāo)志,flag可為:RALARM_ONESHOT(只設(shè)置一次)和RALARM_DAILY(每天都設(shè)置)
cb 鬧鐘時(shí)間到了,喚醒的回調(diào)函數(shù)指針:typedef void (*ralarm_response_cb)(ralarm_t alarm)
userData 設(shè)置鬧鐘時(shí),自帶的用戶數(shù)據(jù)的指針
「返回」 ——
ralarm_t 鬧鐘創(chuàng)建成功,放回鬧鐘句柄
NULL 鬧鐘創(chuàng)建失敗
  1. 函數(shù)說明:
  • ①申請(qǐng)鬧鐘控制塊的空間。
  • ②設(shè)置鬧鐘參數(shù)到控制塊中。
  • ③將鬧鐘加入到鬧鐘鏈表中。
structralarm_setup{
ralarm_flagflag;
structralarm_timetime;
};
typedefstructralarm_setup*ralarm_setup_t;

structralarm{
ralarm_statestate;
structralarm_setupsetup;
ralarm_response_cbcb;
void*userData;
ralarm_list_tlist;
};
typedefstructralarm*ralarm_t;

ralarm_tralarm_create(ralarm_setup_tsetup,ralarm_response_cbcb,void*userData)
{
ralarm_talarm=NULL;

if(setup==NULL){
RALARM_LOGE("Createalarmfailed,SetupparamisNULL");
returnNULL;
}
alarm=RALARM_MALLOC(sizeof(structralarm));//----①
if(alarm==NULL){
RALARM_LOGE("Mallocalarmmemoryfailed");
returnNULL;
}

ralarm_list_init(&alarm->list);//----②
memset((void*)alarm,0,sizeof(structralarm));
memcpy((void*)&alarm->setup,setup,sizeof(structralarm_setup));
alarm->cb=cb;
alarm->userData=userData;

ralarm_mutex_lock(g_container.mutex);
ralarm_list_insert_after(&g_container.list,&alarm->list);//----③
ralarm_mutex_unlock(g_container.mutex);
returnalarm;
}
  • 鬧鐘啟動(dòng):將鬧鐘的狀態(tài)的start bit置為1。
ralarm_err_tralarm_start(ralarm_talarm)
{
if(alarm==NULL){
returnRALARM_ERROR;
}
ralarm_mutex_lock(g_container.mutex);
alarm->state|=RALARM_STATE_START;

ralarm_mutex_unlock(g_container.mutex);
returnRALARM_EOK;
}
  • 鬧鐘停止:將鬧鐘的狀態(tài)的start bit置為0。
ralarm_err_tralarm_stop(ralarm_talarm)
{
if(alarm==NULL){
returnRALARM_ERROR;
}
ralarm_mutex_lock(g_container.mutex);
alarm->state&=~RALARM_STATE_START;

ralarm_mutex_unlock(g_container.mutex);
returnRALARM_EOK;
}
  • 鬧鐘修改:修改鬧鐘的標(biāo)志和鬧鐘的時(shí)間
  1. 參數(shù)說明:
「參數(shù)」 「描述」
alarm 鬧鐘的句柄
setup 要修改鬧鐘的時(shí)間和標(biāo)志參數(shù)
「返回」 ——
RALARM_EOK 修改成功
RALARM_ERROR 修改失敗
ralarm_err_tralarm_modify(ralarm_talarm,ralarm_setup_tsetup)
{
if(alarm==NULL){
returnRALARM_ERROR;
}
ralarm_mutex_lock(g_container.mutex);

memcpy((void*)&alarm->setup,setup,sizeof(structralarm_setup));

ralarm_mutex_unlock(g_container.mutex);
returnRALARM_EOK;
}
  • 刪除鬧鐘:
  1. 函數(shù)說明:
  • ①將鬧鐘的狀態(tài)的start bit置為0。
  • ②將鬧鐘從鬧鐘鏈表中移除。
  • ③釋放鬧鐘的內(nèi)存。
ralarm_err_tralarm_delete(ralarm_talarm)
{
if(alarm==NULL){
returnRALARM_ERROR;
}
ralarm_mutex_lock(g_container.mutex);

alarm->state&=~RALARM_STATE_START;//---①
ralarm_list_remove(&alarm->list);//---②
RALARM_FREE(alarm);//---③
alarm=NULL;

ralarm_mutex_unlock(g_container.mutex);
returnRALARM_EOK;
}

適配簡(jiǎn)單

  • 根據(jù)系統(tǒng)能力,提供獲取時(shí)間方法,創(chuàng)建ralarm的ops并注冊(cè)獲取時(shí)間接口。
structralarm_ops{
ralarm_err_t(*time_get)(ralarm_time_ttime);
};

ralarm_err_tralarm_register_ops(structralarm_ops*ops);
  • 提供刷新節(jié)拍,然后調(diào)用刷新接口。
voidralarm_refresh(void);

RAlarm運(yùn)行邏輯:

  1. 鬧鐘的refresh接口需要用戶提供一個(gè)刷新節(jié)拍,以提供鬧鐘的生命。
  2. refresh皆苦根據(jù)鬧鐘鏈表是否存在已設(shè)置的鬧鐘,選擇發(fā)送事件給更新任務(wù),更新檢測(cè)鬧鐘的狀態(tài)。
  3. 如下圖:當(dāng)檢測(cè)鬧鐘鏈表無(wú)設(shè)置的鬧鐘,則不會(huì)發(fā)送事件給更新任務(wù)
9fa87b5c-f514-11ed-9c1d-dac502259ad0.png
  1. 如下圖:
  • 當(dāng)用戶創(chuàng)建了鬧鐘,則會(huì)將鬧鐘掛在鬧鐘量表中。
  • 刷新節(jié)拍調(diào)用refresh之后,發(fā)送事件給更新任務(wù),然后調(diào)用wakeup檢測(cè)鬧鐘的狀態(tài)。
  • 如果某個(gè)鬧鐘時(shí)間到,則會(huì)調(diào)用對(duì)應(yīng)鬧鐘的回調(diào)函數(shù)。
9fba7582-f514-11ed-9c1d-dac502259ad0.png

RAlarm的使用

  • 在RT-Thread下使用ralarm組件:
    • ① 鬧鐘的處理函數(shù),當(dāng)鬧鐘時(shí)間到了,則會(huì)調(diào)用這個(gè)函數(shù)。
    • ② 提供給ralarm組件時(shí)間接口。
    • ③ 創(chuàng)建ops,提供時(shí)間接口。
    • ④ 軟件定時(shí)器的處理函數(shù),調(diào)用ralarm的刷新函數(shù),提供刷新節(jié)拍。
    • ⑤ ralarm組件初始化,注冊(cè)ops。
    • ⑥ 創(chuàng)建鬧鐘。
    • ⑦ 創(chuàng)建一個(gè)軟件定時(shí)器,為ralarm組件提供刷新節(jié)拍。
staticrt_timer_ttimer;
ralarm_talarm_test=NULL;

staticvoidalarm_handler(ralarm_talarm)//---①
{
rt_kprintf("Time:%02d:%02d:%02drn",alarm->setup.time.hour,
alarm->setup.time.minute,alarm->setup.time.second);
ralarm_stop(alarm);
ralarm_dump();
}

staticralarm_err_talarm_time_get(ralarm_time_ttimer)//---②
{
time_tcurrent;
structtm*local;

time(¤t);
local=localtime(¤t);
timer->hour=local->tm_hour;
timer->minute=local->tm_min;
timer->second=local->tm_sec;
returnRALARM_EOK;
}

staticstructralarm_opsops={//---③
.time_get=alarm_time_get,
};

staticvoidtime_handler(void*param)//---④
{
ralarm_refresh();
}

intmain(void)
{
ralarm_init();//---⑤
ralarm_register_ops(&ops);

structralarm_setupsetup;
setup.flag=RALARM_DAILY;
setup.time.hour=15;
setup.time.minute=0;
setup.time.second=0;

alarm_test=ralarm_create(&setup,alarm_handler,NULL);//---⑥
ralarm_start(alarm_test);

ralarm_dump();

timer=rt_timer_create("timer",time_handler,//---⑦
RT_NULL,800,
RT_TIMER_FLAG_PERIODIC);
if(timer!=RT_NULL)
rt_timer_start(timer);
}
  • 驗(yàn)證結(jié)果:
9fcab2a8-f514-11ed-9c1d-dac502259ad0.png

9fdf63c4-f514-11ed-9c1d-dac502259ad0.png


審核編輯黃宇


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    8459

    瀏覽量

    150748
  • RTOS
    +關(guān)注

    關(guān)注

    21

    文章

    809

    瀏覽量

    119366
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    SILABS CP2103芯片是否不依賴于我錯(cuò)過的微/ picoblaze處理器?

    /TechnicalDocs/CP2103.pdf幾乎沒有說明這個(gè)芯片的使用情況(除了告訴我RTS和CTS之外)活躍的低)。這個(gè)芯片的vhdl或verilog示例代碼是否不依賴于我錯(cuò)過的微/ picoblaze處理器
    發(fā)表于 07-23 13:00

    一種不依賴于棋盤格等輔助標(biāo)定物體實(shí)現(xiàn)像素級(jí)相機(jī)和激光雷達(dá)自動(dòng)標(biāo)定的方法

    主要內(nèi)容本文提出了一種不依賴于棋盤格等輔助標(biāo)定物體,實(shí)現(xiàn)像素級(jí)相機(jī)和激光雷達(dá)自動(dòng)標(biāo)定的方法。方法直接從點(diǎn)云中提取3D邊特征,一避免遮擋問題,并且使用了精確度更高的深度連續(xù)邊。文中首先指出:以下四種
    發(fā)表于 09-01 07:42

    是否可以在主內(nèi)核處于喚醒狀態(tài)時(shí)在ESP32-S3上使用ULP?

    我認(rèn)為 ULP 協(xié)處理器是 ESP32 系列中的一個(gè)獨(dú)立硬件單元,不依賴于主內(nèi)核。如果這是真的,那么它可以在主內(nèi)核運(yùn)行時(shí)用作硬件??看門狗(比如計(jì)算滴答)。不確定這是否可行,是否值得嘗
    發(fā)表于 03-02 07:51

    采用單片機(jī)設(shè)計(jì)的電子鬧鐘硬件方案

    采用單片機(jī)設(shè)計(jì)的電子鬧鐘硬件方案 1、 電子鬧鐘硬件系統(tǒng)框架:設(shè)計(jì)出電子鬧鐘的基本整體框架。2、 電子
    發(fā)表于 04-02 11:55 ?200次下載

    據(jù)調(diào)查64%的人表示:日常生活中不依賴物聯(lián)網(wǎng)設(shè)備

    大多數(shù)人(64%)表示,他們不依賴連網(wǎng)設(shè)備來(lái)完成日?;顒?dòng),這一比例是36%的人表示他們依靠設(shè)備來(lái)度過日常生活的兩倍。領(lǐng)先的B2B研究、評(píng)級(jí)和評(píng)論公司Clutch一項(xiàng)新調(diào)查發(fā)現(xiàn),67%擁有連網(wǎng)設(shè)備的人擁有智能家用電器,如智能冰箱、烤箱或電視。
    發(fā)表于 10-27 10:13 ?1830次閱讀

    量子技術(shù)革GPS的命:不依賴衛(wèi)星就可以進(jìn)行導(dǎo)航

    導(dǎo)航衛(wèi)星系統(tǒng)(GNSS),這類系統(tǒng)可以發(fā)送和接收來(lái)自繞地球運(yùn)行的衛(wèi)星的信號(hào)。量子加速度計(jì)是一個(gè)獨(dú)立的系統(tǒng),不依賴任何外部信號(hào)。 這一點(diǎn)尤其重要,因?yàn)樾l(wèi)星信號(hào)可能因高層建筑物等阻礙因素而無(wú)法使用,或者可能被堵塞、模仿或拒絕,因而無(wú)法進(jìn)行
    發(fā)表于 11-19 16:22 ?364次閱讀

    PHP簡(jiǎn)單實(shí)現(xiàn)不依賴于Unix系統(tǒng)Cron的定時(shí)任務(wù)程序資料說明

    本文檔的主要內(nèi)容詳細(xì)介紹的是PHP簡(jiǎn)單實(shí)現(xiàn)不依賴于Unix系統(tǒng)Cron的定時(shí)任務(wù)程序資料說明。
    發(fā)表于 03-01 16:52 ?2次下載
    PHP簡(jiǎn)單實(shí)現(xiàn)<b class='flag-5'>不依賴</b>于Unix系統(tǒng)Cron的定時(shí)任務(wù)程序資料說明

    DeFi可以成為加密金融的未來(lái)嗎

    去中心化金融是一種利用去中心化的網(wǎng)絡(luò)將舊的金融產(chǎn)品轉(zhuǎn)化為不依賴中介機(jī)構(gòu)、運(yùn)行透明的協(xié)議的運(yùn)動(dòng)。
    發(fā)表于 09-23 15:19 ?429次閱讀

    INS是一種不依賴于外部信息的自主式導(dǎo)航系統(tǒng)

    慣性導(dǎo)航系統(tǒng)(INS)也稱作慣性參考系統(tǒng),是一種不依賴于外部信息、也不向外部輻射能量(如無(wú)線電導(dǎo)航那樣)的自主式導(dǎo)航系統(tǒng)。其工作環(huán)境不僅包括空中、地面,還可以在水下。 慣性導(dǎo)航的基本工作原理是以牛頓
    發(fā)表于 06-08 15:29 ?2584次閱讀

    一個(gè)種不依賴昂貴檢測(cè)設(shè)備的偏置電流測(cè)試方法

    本篇介紹一個(gè)種不依賴昂貴檢測(cè)設(shè)備的偏置電流測(cè)試方法,同時(shí)配合LTspice仿真增強(qiáng)理解。工程師可以在普通實(shí)驗(yàn)室環(huán)境中,根據(jù)該方法調(diào)整放大器局部電路實(shí)現(xiàn)偏置電流的準(zhǔn)確測(cè)量。 如圖2.36為
    的頭像 發(fā)表于 09-30 16:08 ?3017次閱讀
    一個(gè)種<b class='flag-5'>不依賴</b>昂貴檢測(cè)設(shè)備的偏置電流測(cè)試方法

    以色列成立新研究中心,開發(fā)不依賴GPS的導(dǎo)航系統(tǒng)

    以色列開發(fā)不依賴GPS的導(dǎo)航技術(shù) 據(jù)C4ISR網(wǎng)站2021年3月18日?qǐng)?bào)道,以色列國(guó)防部和以色列航空工業(yè)公司(IAI)成立了一個(gè)新的研究中心,開發(fā)不依賴于易中斷的GPS的導(dǎo)航系統(tǒng)。全球軍事力量都在
    的頭像 發(fā)表于 04-12 09:43 ?1991次閱讀

    智行者發(fā)布國(guó)內(nèi)首款不依賴高精地圖的高級(jí)別自動(dòng)駕駛解決方案

    與市場(chǎng)上其他高速領(lǐng)航系統(tǒng)不同,智行者的H-INP采用了“重感知 輕地圖”的技術(shù)方案,成為國(guó)內(nèi)首款不依賴高精地圖的高級(jí)別自動(dòng)駕駛解決方案。
    的頭像 發(fā)表于 08-19 10:19 ?2474次閱讀

    一個(gè)種不依賴昂貴檢測(cè)設(shè)備的偏置電流測(cè)試方法

    本篇介紹一個(gè)種不依賴昂貴檢測(cè)設(shè)備的偏置電流測(cè)試方法,同時(shí)配合LTspice仿真增強(qiáng)理解。工程師可以在普通實(shí)驗(yàn)室環(huán)境中,根據(jù)該方法調(diào)整放大器局部電路實(shí)現(xiàn)偏置電流的準(zhǔn)確測(cè)量。
    發(fā)表于 02-22 14:17 ?729次閱讀
    一個(gè)種<b class='flag-5'>不依賴</b>昂貴檢測(cè)設(shè)備的偏置電流測(cè)試方法

    原生鴻蒙系統(tǒng)正式發(fā)布,余承東宣布不依賴國(guó)外核心技術(shù)

    ’,標(biāo)志著華為在移動(dòng)操作系統(tǒng)領(lǐng)域邁出了堅(jiān)實(shí)的一步?!?這款原生鴻蒙系統(tǒng)作為中國(guó)自主研發(fā)的移動(dòng)操作系統(tǒng),其最大的亮點(diǎn)在于不依賴于國(guó)外的編程語(yǔ)言和操作系統(tǒng)內(nèi)核等核心技術(shù),實(shí)現(xiàn)了真正的自主可控。這一突破對(duì)于提升我國(guó)在全球科技領(lǐng)域的競(jìng)爭(zhēng)力具有重要意義。 然而,對(duì)于
    的頭像 發(fā)表于 10-23 10:08 ?267次閱讀

    分享一個(gè)跨平臺(tái)通用型GUI框架

    AAGUI是一個(gè)不依賴特定硬件、操作系統(tǒng)的跨平臺(tái)通用型GUI。
    的頭像 發(fā)表于 10-28 09:21 ?225次閱讀
    分享一個(gè)跨平臺(tái)通用型GUI框架