国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

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

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

3天內不再提示

非常實用,推薦一種面向對象思維的單片機程序框架

jf_pJlTbmA9 ? 來源:小麥大叔 ? 作者:小麥大叔 ? 2023-10-24 18:03 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

程序架構重要性

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

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

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

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

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

Demo

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

#include
#include
#include
#include"timeslice.h"

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

//具體的任務函數
voidtask1_hdl()
{
printf(">>task1isrunning...n");
}

voidtask2_hdl()
{
printf(">>task2isrunning...n");
}

voidtask3_hdl()
{
printf(">>task3isrunning...n");
}

voidtask4_hdl()
{
printf(">>task4isrunning...n");
}

voidtask5_hdl()
{
printf(">>task5isrunning...n");
}

//初始化任務對象,并且將任務添加到時間片輪詢調度中
voidtask_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);
}

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

voidtimeslice_tick_thread()
{
while(true)
{
timeslice_tick();
Sleep(10);
}
}

intmain()
{
task_init();

printf(">>tasknum:%dn",timeslice_get_task_num());
printf(">>tasklen:%dn",timeslice_get_task_timeslice_len( task_3));

timeslice_task_del( task_2);
printf(">>delettask2n");
printf(">>task2isexist:%dn",timeslice_task_isexist( task_2));

printf(">>tasknum:%dn",timeslice_get_task_num());
timeslice_task_del( task_5);printf(">>delettask5n");
printf(">>tasknum:%dn",timeslice_get_task_num());
printf(">>task3isexist:%dn",timeslice_task_isexist( task_3));

timeslice_task_add( task_2);printf(">>addtask2n");
printf(">>task2isexist:%dn",timeslice_task_isexist( task_2));

timeslice_task_add( task_5);printf(">>addtask5n");
printf(">>tasknum:%dn",timeslice_get_task_num());

printf("nn========timeslicerunning===========n");

std::threadthread_1(timeslice_exec_thread);
std::threadthread_2(timeslice_tick_thread);

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

return0;
}

運行結果如下:

poYBAGGnJ7OAZ5XZAACMwYJDoAU530.png

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

時間片輪詢架構

其實該部分主要使用了面向對象的思維,使用結構體作為對象,并使用結構體指針作為參數傳遞,這樣作可以節(jié)省資源,并且有著極高的運行效率。

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

h文件:

#ifndef_TIMESLICE_H
#define_TIMESLICE_H

#include"./list.h"

typedefenum
{
TASK_STOP,
TASK_RUN
}IsTaskRun;

typedefstructtimesilce
{
unsignedintid;
void(*task_hdl)(void);
IsTaskRunis_run;
unsignedinttimer;
unsignedinttimeslice_len;
ListObjtimeslice_task_list;
}TimesilceTaskObj;

voidtimeslice_exec(void);
voidtimeslice_tick(void);
voidtimeslice_task_init(TimesilceTaskObj*obj,void(*task_hdl)(void),unsignedintid,unsignedinttimeslice_len);
voidtimeslice_task_add(TimesilceTaskObj*obj);
voidtimeslice_task_del(TimesilceTaskObj*obj);
unsignedinttimeslice_get_task_timeslice_len(TimesilceTaskObj*obj);
unsignedinttimeslice_get_task_num(void);
unsignedchartimeslice_task_isexist(TimesilceTaskObj*obj);

#endifc文件:
#include"./timeslice.h"

staticLIST_HEAD(timeslice_task_list);

voidtimeslice_exec()
{
ListObj*node;
TimesilceTaskObj*task;

list_for_each(node, timeslice_task_list)
{

task=list_entry(node,TimesilceTaskObj,timeslice_task_list);
if(task->is_run==TASK_RUN)
{
task->task_hdl();
task->is_run=TASK_STOP;
}
}
}

voidtimeslice_tick()
{
ListObj*node;
TimesilceTaskObj*task;

list_for_each(node, timeslice_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;
}
}
}
}

unsignedinttimeslice_get_task_num()
{
returnlist_len( timeslice_task_list);
}

voidtimeslice_task_init(TimesilceTaskObj*obj,void(*task_hdl)(void),unsignedintid,unsignedinttimeslice_len)
{
obj->id=id;
obj->is_run=TASK_STOP;
obj->task_hdl=task_hdl;
obj->timer=timeslice_len;
obj->timeslice_len=timeslice_len;
}

voidtimeslice_task_add(TimesilceTaskObj*obj)
{
list_insert_before( timeslice_task_list, obj->timeslice_task_list);
}

voidtimeslice_task_del(TimesilceTaskObj*obj)
{
if(timeslice_task_isexist(obj))
list_remove( obj->timeslice_task_list);
else
return;
}

unsignedchartimeslice_task_isexist(TimesilceTaskObj*obj)
{
unsignedcharisexist=0;
ListObj*node;
TimesilceTaskObj*task;

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

returnisexist;
}

unsignedinttimeslice_get_task_timeslice_len(TimesilceTaskObj*obj)
{
returnobj->timeslice_len;
}

底層侵入式雙向鏈表

該鏈表是linux內核中使用十分廣泛,也十分經典,其原理具體可以參考文章:

https://www.cnblogs.com/skywang12345/p/3562146.html

h文件:

#ifndef_LIST_H
#define_LIST_H
#defineoffset_of(type,member)(unsignedlong) ((type*)0)->member
#definecontainer_of(ptr,type,member)((type*)((char*)(ptr)-offset_of(type,member)))

typedefstructlist_structure
{
structlist_structure*next;
structlist_structure*prev;
}ListObj;

#defineLIST_HEAD_INIT(name){ (name), (name)}
#defineLIST_HEAD(name)ListObjname=LIST_HEAD_INIT(name)

voidlist_init(ListObj*list);
voidlist_insert_after(ListObj*list,ListObj*node);
voidlist_insert_before(ListObj*list,ListObj*node);
voidlist_remove(ListObj*node);
intlist_isempty(constListObj*list);
unsignedintlist_len(constListObj*list);

#definelist_entry(node,type,member)
container_of(node,type,member)

#definelist_for_each(pos,head)
for(pos=(head)->next;pos!=(head);pos=pos->next)

#definelist_for_each_safe(pos,n,head)
for(pos=(head)->next,n=pos->next;pos!=(head);
pos=n,n=pos->next)

#endif

c文件:

#include"list.h"

voidlist_init(ListObj*list)
{
list->next=list->prev=list;
}

voidlist_insert_after(ListObj*list,ListObj*node)
{
list->next->prev=node;
node->next=list->next;

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

voidlist_insert_before(ListObj*list,ListObj*node)
{
list->prev->next=node;
node->prev=list->prev;

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

voidlist_remove(ListObj*node)
{
node->next->prev=node->prev;
node->prev->next=node->next;

node->next=node->prev=node;
}

intlist_isempty(constListObj*list)
{
returnlist->next==list;
}

unsignedintlist_len(constListObj*list)
{
unsignedintlen=0;
constListObj*p=list;
while(p->next!=list)
{
p=p->next;
len++;
}

returnlen;
}

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

來源:小麥大叔

免責聲明:本文為轉載文章,轉載此文目的在于傳遞更多信息,版權歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權問題,請聯系小編進行處理

審核編輯 黃宇

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

    關注

    6076

    文章

    45494

    瀏覽量

    670258
  • 框架
    +關注

    關注

    0

    文章

    404

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    面向單片機、事件驅動的嵌入式開發(fā)平臺介紹

    EventOS,是面向單片機、事件驅動的嵌入式開發(fā)平臺。它主要有兩大技術特色:是事件驅動,二是超輕量。EventOS以及其母項目EventOS,目標是開發(fā)
    發(fā)表于 12-05 06:26

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

    最適合單片機開發(fā)的編程語言實在太過晦澀難懂,學習起來非常的不方便,并且每一種單片機的匯編指令有很大區(qū)別,所以想把
    發(fā)表于 11-28 07:37

    單片機開發(fā)中常用的三軟件架構介紹

    // ... 找零邏輯 P2 = 0xFF;// 關閉機械臂} 6.面向對象架構STM32的庫,就是一種面向對象的架構。 不過在
    發(fā)表于 11-26 08:05

    C語言和單片機C語言有什么差異

    單片機c語言相對于普通C語言增加了些基本的指令,還有變量的賦值是16進制,當然單片機c語言只牽涉到普通c語言非常基礎部分。 主要的差異具體體現在: 1、
    發(fā)表于 11-14 07:55

    PYQT 應用程序框架及開發(fā)工具

    大家好,本團隊此次分享的內容為開發(fā)過程中使用到的PYQT 應用程序框架及開發(fā)工具。 pYqt 是個多平臺的 python 圖形用戶界面應用程序
    發(fā)表于 10-29 07:15

    單片機個承載科技與工程思維的核心平臺

    在現代社會中,科技的快速發(fā)展推動了各個行業(yè)和技術的革新。單片機(Single Chip Computer)作為一種集成化的電子系統,正在逐漸成為連接數字世界與物理世界的橋梁。無論是智能家居、自動駕駛
    的頭像 發(fā)表于 09-29 01:07 ?572次閱讀

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

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

    一種適用于動態(tài)環(huán)境的自適應先驗場景-對象SLAM框架

    由于傳統視覺SLAM在動態(tài)場景中容易會出現嚴重的定位漂移,本文提出了一種新穎的基于場景-對象的可靠性評估框架,該框架通過當前幀質量指標以及相對于可靠參考幀的場景變化,全面評估SLAM的
    的頭像 發(fā)表于 08-19 14:17 ?873次閱讀
    <b class='flag-5'>一種</b>適用于動態(tài)環(huán)境的自適應先驗場景-<b class='flag-5'>對象</b>SLAM<b class='flag-5'>框架</b>

    單片機原理及應用詳解

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

    怎么測單片機系統頻率

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

    單片機怎么燒程序

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

    STC單片機范例程序

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

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

    如題,2.4寸TFT彩屏配套測試程序-51單片機。
    發(fā)表于 06-04 16:26 ?0次下載

    單片機和伺服有什么區(qū)別

    : 1. 定義與功能 特性 單片機(Microcontroller) 伺服系統(Servo System) 定義 一種集成CPU、內存、I/O接口的微型計算機芯片,用于控制設備。 一種由伺服電機、編碼器
    的頭像 發(fā)表于 05-26 09:18 ?849次閱讀

    一種新型直流電機控制器

    以前控制直流電機多由單片機完成。該方式缺點是接口繁瑣、速度慢,且不易在高溫、高壓等惡劣環(huán)境下工作[1]。采用一種新型直流電機控制器——DSP 控制器解決了單片機控制的缺點,其具備很多優(yōu)點,該控制器
    發(fā)表于 03-25 15:25