日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

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

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

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

單片機程序時間輪片法框架

strongerHuang ? 來源:ERYUESANHI ? 作者:ERYUESANHI ? 2021-08-26 11:07 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

來源 | ERYUESANHI

編排 | strongerHuang

今天分享一篇單片機程序框架的文章。

程序架構(gòu)重要性

很多人尤其是初學者在寫代碼的時候往往都是想一點寫一點,最開始沒有一個整體的規(guī)劃,導致后面代碼越寫越亂,bug不斷。

最終代碼跑起來看似沒有問題(有可能也真的沒有問題),但是要加一個功能的時候會浪費大量的時間,甚至導致整個代碼的崩潰。

所以,在一個項目開始的時候多花一些時間在代碼的架構(gòu)設(shè)計上是十分有必要的。代碼架構(gòu)確定好了之后你會發(fā)現(xiàn)敲代碼的時候會特別快,并且在后期調(diào)試的時候也不會像無頭蒼蠅一樣胡亂找問題。當然,調(diào)試也是一門技術(shù)。

在學習實時操作系統(tǒng)的過程中,發(fā)現(xiàn)實時操作系統(tǒng)框架與個人的業(yè)務(wù)代碼之間的耦合性就非常低,都是只需要將業(yè)務(wù)代碼通過一定的接口函數(shù)注冊好后就交給操作系統(tǒng)托管了,十分方便。

但是操作系統(tǒng)的調(diào)度過于復雜,這里就使用操作系統(tǒng)的思維方式來重構(gòu)這個時間片輪詢框架。實現(xiàn)該框架的完全解耦,用戶只需要包含頭文件,并且在使用過程中不需要改動已經(jīng)寫好的庫文件。

Demo

首先來個demo,該demo是使用電腦開兩個線程:一個線程模擬單片機的定時器中斷產(chǎn)生時間片輪詢個時鐘,另一個線程則模擬主函數(shù)中一直運行的時間片輪詢調(diào)度程序。

#include 《thread》#include 《stdio.h》#include 《windows.h》#include “timeslice.h”

// 創(chuàng)建5個任務(wù)對象TimesilceTaskObj task_1, task_2, task_3, task_4, task_5;

// 具體的任務(wù)函數(shù)void task1_hdl(){ printf(“》》 task 1 is running 。..

”);}

void task2_hdl(){ printf(“》》 task 2 is running 。..

”);}

void task3_hdl(){ printf(“》》 task 3 is running 。..

”);}

void task4_hdl(){ printf(“》》 task 4 is running 。..

”);}

void task5_hdl(){ printf(“》》 task 5 is running 。..

”);}

// 初始化任務(wù)對象,并且將任務(wù)添加到時間片輪詢調(diào)度中void task_init(){ timeslice_task_init(&task_1, task1_hdl, 1, 10); timeslice_task_init(&task_2, task2_hdl, 2, 20); timeslice_task_init(&task_3, task3_hdl, 3, 30); timeslice_task_init(&task_4, task4_hdl, 4, 40); timeslice_task_init(&task_5, task5_hdl, 5, 50); timeslice_task_add(&task_1); timeslice_task_add(&task_2); timeslice_task_add(&task_3); timeslice_task_add(&task_4); timeslice_task_add(&task_5);}

// 開兩個線程模擬在單片機上的運行過程void timeslice_exec_thread(){ while (true) { timeslice_exec(); }}

void timeslice_tick_thread(){ while (true) { timeslice_tick(); Sleep(10); }}

int main(){ task_init();

printf(“》》 task num: %d

”, timeslice_get_task_num()); printf(“》》 task len: %d

”, timeslice_get_task_timeslice_len(&task_3));

timeslice_task_del(&task_2); printf(“》》 delet task 2

”); printf(“》》 task 2 is exist: %d

”, timeslice_task_isexist(&task_2));

printf(“》》 task num: %d

”, timeslice_get_task_num());

timeslice_task_del(&task_5); printf(“》》 delet task 5

”);

printf(“》》 task num: %d

”, timeslice_get_task_num());

printf(“》》 task 3 is exist: %d

”, timeslice_task_isexist(&task_3)); timeslice_task_add(&task_2); printf(“》》 add task 2

”); printf(“》》 task 2 is exist: %d

”, timeslice_task_isexist(&task_2));

timeslice_task_add(&task_5); printf(“》》 add task 5

”);

printf(“》》 task num: %d

”, timeslice_get_task_num());

printf(“

========timeslice running===========

”);

std::thread thread_1(timeslice_exec_thread); std::thread thread_2(timeslice_tick_thread);

thread_1.join(); thread_2.join();

return 0;}

由以上例子可見,這個框架使用十分方便,甚至可以完全不知道其原理,僅僅通過幾個簡單的接口就可以迅速創(chuàng)建任務(wù)并加入到時間片輪詢的框架中,十分好用。

時間片輪詢架構(gòu)

其實該部分主要使用了面向?qū)ο蟮乃季S,使用結(jié)構(gòu)體作為對象,并使用結(jié)構(gòu)體指針作為參數(shù)傳遞,這樣作可以節(jié)省資源,并且有著極高的運行效率。

其中最難的部分是侵入式鏈表的使用,這種鏈表在一些操作系統(tǒng)內(nèi)核中使用十分廣泛,這里是參考RT-Thread實時操作系統(tǒng)中的侵入式鏈表實現(xiàn)。

h文件:

#ifndef _TIMESLICE_H#define _TIMESLICE_H

#include “。/list.h”

typedef enum { TASK_STOP, TASK_RUN} IsTaskRun;

typedef struct timesilce{ unsigned int id; void (*task_hdl)(void); IsTaskRun is_run; unsigned int timer; unsigned int timeslice_len; ListObj timeslice_task_list;} TimesilceTaskObj;

void timeslice_exec(void);void timeslice_tick(void);void timeslice_task_init(TimesilceTaskObj* obj, void (*task_hdl)(void), unsigned int id, unsigned int timeslice_len);void timeslice_task_add(TimesilceTaskObj* obj);void timeslice_task_del(TimesilceTaskObj* obj);unsigned int timeslice_get_task_timeslice_len(TimesilceTaskObj* obj);unsigned int timeslice_get_task_num(void);unsigned char timeslice_task_isexist(TimesilceTaskObj* obj);

#endif

c文件:

#include “。/timeslice.h”

static LIST_HEAD(timeslice_task_list);

void timeslice_exec(){ ListObj* node; TimesilceTaskObj* task;

list_for_each(node, ×lice_task_list) { task = list_entry(node, TimesilceTaskObj, timeslice_task_list); if (task-》is_run == TASK_RUN) { task-》task_hdl(); task-》is_run = TASK_STOP; } }}

void timeslice_tick(){ ListObj* node; TimesilceTaskObj* task;

list_for_each(node, ×lice_task_list) { task = list_entry(node, TimesilceTaskObj, timeslice_task_list); if (task-》timer != 0) { task-》timer--; if (task-》timer == 0) { task-》is_run = TASK_RUN; task-》timer = task-》timeslice_len; } } }}

unsigned int timeslice_get_task_num(){ return list_len(×lice_task_list);}

void timeslice_task_init(TimesilceTaskObj* obj, void (*task_hdl)(void), unsigned int id, unsigned int timeslice_len){ obj-》id = id; obj-》is_run = TASK_STOP; obj-》task_hdl = task_hdl; obj-》timer = timeslice_len; obj-》timeslice_len = timeslice_len;}

void timeslice_task_add(TimesilceTaskObj* obj){ list_insert_before(×lice_task_list, &obj-》timeslice_task_list);}

void timeslice_task_del(TimesilceTaskObj* obj){ if (timeslice_task_isexist(obj)) list_remove(&obj-》timeslice_task_list); else return;}

unsigned char timeslice_task_isexist(TimesilceTaskObj* obj){ unsigned char isexist = 0; ListObj* node; TimesilceTaskObj* task;

list_for_each(node, ×lice_task_list) { task = list_entry(node, TimesilceTaskObj, timeslice_task_list); if (obj-》id == task-》id) isexist = 1; }

return isexist;}

unsigned int timeslice_get_task_timeslice_len(TimesilceTaskObj* obj){ return obj-》timeslice_len;}

底層侵入式雙向鏈表

該鏈表是linux內(nèi)核中使用十分廣泛,也十分經(jīng)典,其原理具體可以參考文章:https://www.cnblogs.com/skywang12345/p/3562146.html

h文件:

#ifndef _LIST_H#define _LIST_H

#define offset_of(type, member) (unsigned long) &((type*)0)-》member#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offset_of(type, member)))

typedef struct list_structure{ struct list_structure* next; struct list_structure* prev;} ListObj;

#define LIST_HEAD_INIT(name) {&(name), &(name)}#define LIST_HEAD(name) ListObj name = LIST_HEAD_INIT(name)

void list_init(ListObj* list);void list_insert_after(ListObj* list, ListObj* node);void list_insert_before(ListObj* list, ListObj* node);void list_remove(ListObj* node);int list_isempty(const ListObj* list);unsigned int list_len(const ListObj* list);

#define list_entry(node, type, member) container_of(node, type, member)

#define list_for_each(pos, head) for (pos = (head)-》next; pos != (head); pos = pos-》next)

#define list_for_each_safe(pos, n, head) for (pos = (head)-》next, n = pos-》next; pos != (head); pos = n, n = pos-》next)

#endif

c文件:

#include “l(fā)ist.h”

void list_init(ListObj* list){ list-》next = list-》prev = list;}

void list_insert_after(ListObj* list, ListObj* node){ list-》next-》prev = node; node-》next = list-》next;

list-》next = node; node-》prev = list;}

void list_insert_before(ListObj* list, ListObj* node){ list-》prev-》next = node; node-》prev = list-》prev;

list-》prev = node; node-》next = list;}

void list_remove(ListObj* node){ node-》next-》prev = node-》prev; node-》prev-》next = node-》next;

node-》next = node-》prev = node;}

int list_isempty(const ListObj* list){ return list-》next == list;}

unsigned int list_len(const ListObj* list){ unsigned int len = 0; const ListObj* p = list; while (p-》next != list) { p = p-》next; len++; }

return len;}

到此,一個全新的,完全解耦的,十分方便易用時間片輪詢框架完成。

責任編輯:haq

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

    關(guān)注

    6078

    文章

    45593

    瀏覽量

    673989
  • 框架
    +關(guān)注

    關(guān)注

    0

    文章

    404

    瀏覽量

    18501
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3849

    瀏覽量

    85493

原文標題:單片機面向?qū)ο笏季S的架構(gòu):時間輪片法

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    單片機里的程序運行方式

    我們想要理解單片機是如何運行程序的,我們首先需要了解單片機的組成,我們這里以80C51單片機為例來理解程序
    發(fā)表于 01-16 06:57

    單片機如何燒錄程序

    單片機如何燒錄程序
    發(fā)表于 01-08 07:04

    一文說透了如何實現(xiàn)單片機的多任務(wù)并發(fā)!

    資源,并且避免出現(xiàn)資源爭搶和堵塞的情況。 在單片機多任務(wù)并發(fā)中,常見的任務(wù)調(diào)度方式有兩種: 1. 時間輪轉(zhuǎn)法 時間輪轉(zhuǎn)法是多任務(wù)并發(fā)中
    發(fā)表于 01-06 06:46

    單片機解密是什么?

    ,以保護內(nèi)程序。 如果在編程時加密鎖定位被使能(鎖定),就無法用普通編程器直接讀取單片機內(nèi)的程序,這就叫單片機加密。
    發(fā)表于 12-30 08:19

    單片機的入門準備

    基礎(chǔ),學習單片機就只要花幾周的時間就能上手。但學習單片機時,主要從單片機的寄存器開始,其中特殊功能寄存器是重點,學會之后,就可以學習單片機
    發(fā)表于 12-22 07:39

    單片機程序的執(zhí)行

    更快的SRAM中,以得到更快的執(zhí)行速度。而對于,單片機而言工作頻率也就幾M,幾十M,從Flash中與從RAM中讀的差異可能并不明顯,不會成為程序執(zhí)行的瓶頸。 而對于PC而言,F(xiàn)lash的速度太慢
    發(fā)表于 12-04 06:20

    為什么單片機還在用C語言編程?

    ,只是C語言是最適合單片機編程的高級語言。 一、單片機編程的特點 1.對單片機編程來說,我們首先要考慮的是單片機程序空間和數(shù)據(jù)空間都
    發(fā)表于 11-28 07:37

    單片機燒錄原理是怎樣的?輝芒微單片機燒錄程序詳細步驟講解

    燒錄(Programming)就是把 .hex/.bin 文件里的機器碼搬運進單片機內(nèi) Flash 的過程。輝芒微(FMD)單片機內(nèi)部有一塊 自舉 BootROM,上電時會先跑這段程序
    的頭像 發(fā)表于 09-17 16:14 ?3224次閱讀
    <b class='flag-5'>單片機</b>燒錄原理是怎樣的?輝芒微<b class='flag-5'>單片機</b>燒錄<b class='flag-5'>程序</b>詳細步驟講解

    單片機原理及應用詳解

    單片機(Microcontroller Unit, MCC) ?是一種集成計算機核心功能(CPU、存儲器、I/O接口等)的微型芯片,廣泛應用于嵌入式系統(tǒng)中。以下是其原理及應用的詳細介紹: 一、單片機
    的頭像 發(fā)表于 08-11 13:57 ?2840次閱讀

    單片機的儲存優(yōu)點是什么

    單片機作為嵌入式系統(tǒng)的核心,其儲存系統(tǒng)是實現(xiàn)數(shù)據(jù)存儲與程序運行的關(guān)鍵部分。與獨立存儲芯片相比,單片機的儲存單元在集成度、功耗、可靠性等方面具備獨特優(yōu)勢,這些優(yōu)點使其能適應從消費電子到工業(yè)控制的多樣化
    的頭像 發(fā)表于 07-31 10:09 ?837次閱讀

    怎么測單片機系統(tǒng)頻率

    單片機系統(tǒng)頻率是指單片機工作時的時鐘頻率,它直接影響單片機的運行速度和處理能力,準確測量系統(tǒng)頻率對單片機應用開發(fā)、程序調(diào)試和性能優(yōu)化具有重要
    的頭像 發(fā)表于 07-25 11:39 ?1105次閱讀

    單片機怎么燒程序

    單片機程序是將編寫好的程序代碼寫入單片機內(nèi)部存儲單元,讓單片機按照預設(shè)邏輯工作的過程,是單片機
    的頭像 發(fā)表于 07-23 11:47 ?2072次閱讀

    單片機直流電機調(diào)速原理

    在工業(yè)自動化、智能設(shè)備等領(lǐng)域,直流電機的調(diào)速控制至關(guān)重要,而單片機憑借其靈活的控制能力,成為實現(xiàn)直流電機精準調(diào)速的核心部件。單片機直流電機調(diào)速技術(shù)通過程序控制,能讓電機在不同工況下保持穩(wěn)定的轉(zhuǎn)速
    的頭像 發(fā)表于 07-17 13:42 ?936次閱讀

    STC單片機范例程序

    電子發(fā)燒友網(wǎng)站提供《STC單片機范例程序.zip》資料免費下載
    發(fā)表于 06-04 16:27 ?10次下載

    2.4寸TFT彩屏配套測試程序-51單片機

    如題,2.4寸TFT彩屏配套測試程序-51單片機。
    發(fā)表于 06-04 16:26 ?0次下載
    秦皇岛市| 兴义市| 怀仁县| 柳河县| 怀柔区| 海南省| 凤山县| 呼图壁县| 新晃| 合山市| 亳州市| 邹城市| 界首市| 隆子县| 壶关县| 罗城| 东光县| 梁平县| 始兴县| 长阳| 盐边县| 饶河县| 蓝田县| 沛县| 商河县| 罗源县| 苏州市| 南澳县| 汾阳市| 石景山区| 宾川县| 宝鸡市| 肥城市| 盐亭县| 辉南县| 安陆市| 乐至县| 甘泉县| 商城县| 白城市| 绿春县|