嵌入式驅動學習第一周——內核的中斷機制

前言

?? 本文介紹中斷機制,中斷作為需要頻繁使用的功能,本文將詳細介紹linux內核中的中斷機制。

?? 嵌入式驅動學習專欄將詳細記錄博主學習驅動的詳細過程,未來預計四個月將高強度更新本專欄,喜歡的可以關注本博主并訂閱本專欄,一起討論一起學習。現在關注就是老粉啦!

行文目錄

  • 前言
  • 1. 中斷機制介紹
    • 1.1 中斷概述
    • 1.2 中斷的作用:
    • 1.3 中斷的產生:
  • 2. 中斷實現原理
    • 2.1 中斷處理流程
    • 2.2 中斷向量表
  • 3. 中斷來源
    • 3.1 軟件中斷
      • 3.1.1 CPU異常
      • 3.1.2 指令中斷
    • 3.2 硬件中斷
      • 3.2.1 外設中斷
      • 3.2.2 處理器間中斷
  • 4. 上半部與下半部
    • 4.1 軟中斷
    • 4.2 tasklet
    • 4.3 工作隊列
  • 5. 中斷的API
  • 參考資料

1. 中斷機制介紹

1.1 中斷概述

?? 當你在刷手機的時候,此時突然npy打電話來了,于是你退出刷手機狀態,接聽npy電話,此過程即為中斷。

?? 簡單來說,中斷會讓CPU停止正在執行的程序,轉而讓CPU執行中斷處理函數,執行完再返回原程序。

?? 另外,整個操作系統就是一個中斷驅動的死循環,即裸機開發中常寫的while(true) {}。其他所有的事情都是由操作系統提前注冊的中斷機制和其對應的中斷處理函數完成。

1.2 中斷的作用:

?? 中斷主要有4個用途:外設異步通知CPUCPU間發送消息處理CPU異常實現系統調用

1.3 中斷的產生:

?? 中斷信號的產生有以下4個來源:

?? 1. 外設 :外設產生的中斷信號是異步的,一般也叫硬件中斷,硬件中斷按照是否可以屏蔽分為可屏蔽中斷和不可屏蔽中斷,例如:網卡、磁盤、定時器都可以產生硬件中斷。

?? 2. CPU:一個CPU向另一個CPU發送中斷,叫做IPI(處理器間中斷),是一種特殊的硬件中斷,也是異步的。

?? 3. CPU異常:CPU在執行指令的過程中發現異常會向自己發送中斷信號,這種中斷是同步的,一般也叫做軟件中斷。

?? 4. 中斷指令:直接用CPU指令來產生中斷信號,這種中斷和CPU異常一樣是同步的,也可以叫做軟件中斷。例如,中斷指令int 0x80可以用來實現系統調用。

2. 中斷實現原理

2.1 中斷處理流程

?? 在單片機或裸機開發中,中斷的處理方法是:

①、使能中斷,初始化相應的寄存器
②、注冊中斷服務函數,也就是向 irqTable 數組的指定標號處寫入中斷服務函數
③、中斷發生以后進入 IRQ 中斷服務函數,在 IRQ 中斷服務函數在數組 irqTable 里面查找具體的中斷處理函數,找到以后執行相應的中斷處理函數。

?? 中斷的執行時間不可以過長,否則會影響對新的中斷信號的響應性,所以要盡量縮短中斷執行場景的時間,為此對異步中斷的處理方法有兩種:

?? 1、立即完全處理

?? 對于簡單好處理的異步中斷可以立即進行完全處理。

?? 2、立即預處理(上半部)+稍后完全處理(下半部)

?? 對于處理起來耗時的可以采取立即預處理加稍后完全處理的方式來實現中斷。 立即預處理只能用直接處理來實現,而稍后完全處理的方法分兩類:直接中斷后處理有 softirq(軟中斷)、tasklet(微任務)、線程化中斷后處理有workqueue(工作隊列)、threaded_irq(中斷線程)。

?? 此處有一個概念:硬件中斷、軟件中斷、硬中斷、軟中斷是不同的概念,前兩個是中斷來源,后兩個是中斷處理方式。

2.2 中斷向量表

?? 我們每個人都有各自的身份證,代表每個人的唯一id,這樣通過身份證就可以指定唯一的人。中斷也是這樣的,不同的中斷信號有不同的處理方式,那么系統如何區分呢,即通過中斷向量號。中斷向量號是一個整數,CPU收到一個中斷信號會根據這個信號的中斷的向量號去查詢中斷向量表,根據中斷向量表調用相應的處理函數。

?? 中斷向量表是一個表,表里面存放的是中斷向量。中斷服務程序的入口地址或存放中端服務程序的首地址成為中斷向量,因此中斷向量表是一系列中斷服務程序入口地址組成的表。

3. 中斷來源

3.1 軟件中斷

?? 軟件中斷主要是兩類:CPU異常和指令中斷。

3.1.1 CPU異常

?? CPU在執行過程中遇到異常就會給自己發送異常信號,但是異常信號不一都是錯誤。

3.1.2 指令中斷

?? 指令中斷是因為執行指令而產生了中斷,指令中斷是執行特定指令而發生的中斷,設計這些指令的目的就是為了產生中斷。其中INT n可以產生任意中斷,Linux用int ix80來作為系統調用的指令。

3.2 硬件中斷

?? 硬件中斷分為外設中斷和處理器間中斷(IPI)。

3.2.1 外設中斷

?? 外設中斷和軟件中斷有一個很大的不同,軟件中斷是CPU自己給自己發送中斷,而外設中斷是需要外設發送中斷給CPU。顯然不可能將所有外設都直接連到CPU上,因此需要一個中間設備,替CPU連接到所有外設接受中斷信號,這個設備叫中斷控制器

?? 不同的架構有不同的中斷控制器,比如STM32這種Cortex-M內核的單片機叫NVIC,Cortex-A中叫GIC,x86上Intel開發的叫APIC。

3.2.2 處理器間中斷

4. 上半部與下半部

?? 上半部希望執行時間快,不會占用很長時間的處理;下半部多用于處理耗時的代碼,保證中斷函數的快進快出。

?? 哪部分屬于上半部,哪部分屬于下半部沒有明確規定,可以有一下一些原則:

①、要處理的內容不希望被其他中斷打斷,可以放入上半部
②、如果要處理的任務對時間敏感,可以放上半部
③、如果要處理的任務與硬件有關,可以放上半部

?? 上半部的實現直接編寫中斷處理函數,下半部有多種實現機制,具體下文介紹。

4.1 軟中斷

?? Linux內核中使用結構體softirq_action表示軟中斷。

/** @description : 注冊軟中斷處理函數* @param-nr    : 要開啟的軟中斷* @param-action: 軟中斷對應的處理函數* @return      : 無*/
void open_softirq(int nr, void (*action)(struct softirq_action *))

?? 軟中斷類型枚舉如下:

enum
{HI_SOFTIRQ=0, /* 高優先級軟中斷 */TIMER_SOFTIRQ, /* 定時器軟中斷 */NET_TX_SOFTIRQ, /* 網絡數據發送軟中斷 */NET_RX_SOFTIRQ, /* 網絡數據接收軟中斷 */BLOCK_SOFTIRQ, BLOCK_IOPOLL_SOFTIRQ, TASKLET_SOFTIRQ, /* tasklet 軟中斷 */SCHED_SOFTIRQ, /* 調度軟中斷 */HRTIMER_SOFTIRQ, /* 高精度定時器軟中斷 */RCU_SOFTIRQ, /* RCU 軟中斷 */NR_SOFTIRQS
};

?? 注冊好軟中斷后需要通過raise_softirq() 函數觸發

/** @description: 出發軟中斷* @param-nr   : 要觸發的中斷* @return     : 無*/
void raise_softirq(unsigned int nr)

4.2 tasklet

?? tasklet使用方法簡單、靈活,自帶有鎖機制可以防止多個CPU同時運行,是中斷處理下半部分最常用的一種方法,通過執行中斷處理程序來快速完成上半部分的工作,接著通過調用tasklet使得下半部分的工作得以完成。tasklet執行過程中是可以被硬件中斷所中止的,這樣不會影響系統實時性。是一種將任務推后執行的一種機制。

?? 軟中斷和tasklet之間,建議使用tasklet,用tasklet_struct結構體表示tasklet

struct tasklet_struct
{struct tasklet_struct *next; /* 下一個 tasklet */unsigned long state; /* tasklet 狀態 */atomic_t count; /* 計數器,記錄對 tasklet 的引用數 */void (*func)(unsigned long); /* tasklet 執行的函數 */unsigned long data; /* 函數 func 的參數 */
};

?? 初始化tasklet使用tasklet_init函數:

/** @description: 初始化tasklet* @param-t    : 要初始化的tasklet* @param-func : tasklet的處理函數* @param-data : 要傳遞給func的參數* @return     : 無*/
void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data);

?? 也可以使用宏定義來初始化:

#include <linux/interrupt.h>
/** @description: 初始化tasklet* @param-name : 要初始化的tasklet的名字* @param-func : tasklet的處理函數* @param-data : 要傳遞給func的參數*/
DECLARE_TASKLET(name, func, data)

?? 如果中途不想使用tasklet,則可以調用該函數釋放它,不能在tasklet回調函數調用。和初始化函數作用相反。這個函數首先等待該tasklet執行完畢,然后再將它釋放。

/** @description: 釋放tasklet* @param-t    : 要釋放的tasklet* @return     : 無*/
void tasklet_kill(struct tasklet_struct *t);

?? 在上半部中,使用tasklet_schedule函數使tasklet在合適的時間運行

/** @description: 上半部中調用使tasklet運行* @param-t    : 要調度的tasklet* @return     : 無*/
void tasklet_schedule(struct tasklet_struct *t)

?? tasklet的使用模板:

/* 定義 taselet */
struct tasklet_struct testtasklet;/* tasklet 處理函數 */
void testtasklet_func(unsigned long data)
{/* tasklet 具體處理內容 */
}/* 中斷處理函數 */
irqreturn_t test_handler(int irq, void *dev_id)
{....../* 調度 tasklet */tasklet_schedule(&testtasklet);......
}/* 驅動入口函數 */
static int __init xxxx_init(void)
{....../* 初始化 tasklet */tasklet_init(&testtasklet, testtasklet_func, data);/* 注冊中斷處理函數 */request_irq(xxx_irq, test_handler, 0, "xxx", &xxx_dev);......
}

?? 總結:tasklet被調用之后,其綁定的處理函數不會被馬上運行,需要在合適的時機去運行!在tasklet被調度以后,只要有機會它就會盡可能早的運行,在它還沒有得到運行機會之前,如果一個相同的tasklet又被調度了,那么它仍然只會運行一次。本質上tasklet鏈表不能存在相同的tasklet對象。

4.3 工作隊列

?? 工作隊列是另外一種下半部執行方式,工作隊列在進程上下文執行,工作隊列將要推后的工作交給一個內核線程去執行,因為工作隊列工作在進程上下文,因此工作隊列允許睡眠或重新調度。因此如果你要推后的工作可以睡眠那么就可以選擇工作隊列,否則的話就只能選擇軟中斷或 tasklet。

tasklet機制是在中斷上下文執行,所以在tasklet中不可以執行休眠動作。

關于workqueue與tasklet這兩個機制的選擇,看具體的工作過程有沒有休眠動作

?? Linux內核使用work_struct 結構體表示一個工作

struct work_struct {atomic_long_t data; struct list_head entry;work_func_t func; /* 工作隊列處理函數 */
};

?? 在實際的驅動開發中,我們只需要定義工作(work_struct)即可,關于工作隊列和工作者線程基本不用管。我們需要做的是定義一個work_struct 結構體然后使用宏定義來初始化工作:

// _work表示要初始化的工作,_func是工作對應的處理函數
#define INIT_WORK(_work, _func)

?? 也可以使用 DECLARE_WORK 宏一次性完成工作的創建和初始化

// n表示定義的工作(work_struct), f表示要處理的函數
#define DECLARE_WORK(n, f)

?? 和 tasklet 一樣,工作也是需要調度才能運行的,工作的調度函數為 schedule_work

/** @description: 在上半部中對工作的調度* @param-work : 要調度的工作* @return     : 0,成功;其他值,失敗*/
bool schedule_work(struct work_struct *work)

?? 工作隊列的使用模板:

/* 定義工作(work) */
struct work_struct testwork;
/* work 處理函數 */void testwork_func_t(struct work_struct *work);
{/* work 具體處理內容 */
}/* 中斷處理函數 */
irqreturn_t test_handler(int irq, void *dev_id)
{....../* 調度 work */schedule_work(&testwork);......
}/* 驅動入口函數 */
static int __init xxxx_init(void)
{....../* 初始化 work */INIT_WORK(&testwork, testwork_func_t);/* 注冊中斷處理函數 */request_irq(xxx_irq, test_handler, 0, "xxx", &xxx_dev);......
}

?? 總結:當調用了schedule_work后很快會執行工作函數,工作函數執行完畢后work對象便自動從工作隊列中移除,所以就不需要用戶開發中在驅動卸載函數中手動移除work對象了

5. 中斷的API

?? 在Linux內核中想使用某個中斷需要申請,可以用request_irq函數,其注冊的中斷服務函數屬于中斷處理的上半部,只要中斷觸發,就會立即執行。

/** @description  : 申請中斷向量* @param-irq    : 要申請中斷的中斷號* @param-handler: 中斷處理函數* @param-flags  : 中斷標志* @param-name   : 中斷名字* @param-dev    : 如果flags是IRQF_SHARED的話,dev用來區分不同的中斷,一般情況下將dev設置為設備結構體,dev會傳遞給中斷處理函數的第二個參數* @return       : 0,中斷申請成功,其他負值表示中斷申請失敗,如果返回-EBUSY的話表示中斷已經被申請了。*/
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev);

?? 中斷標志有如下所示幾個:

標志描述
IRQF_SHARED多個設備共享一個中斷線,共享的所有中斷都必須指定此標志。request_irq 函數的 dev 參數就是唯一區分他們的標志
IRQF_ONESHOT單詞觸發,中斷執行一次就結束
IRQF_TRIGGER_NONE無觸發
IRQF_TRIGGER_RISING上升沿觸發
IRQF_TRIGGER_FALLING下降沿觸發
IRQF_TRIGGER_HIGH高電平觸發
IRQF_TRIGGER_LOW低電平觸發

?? 表中的標志可以通過 "|" 來實現各種組合。

/** @description  : 釋放相應的中斷* @param-irq    : 要釋放中斷的中斷號* @param-dev    : 如果flags是IRQF_SHARED的話,dev用來區分不同的中斷。共享中斷只有在釋放最后中斷處理函數的時候才會被禁止掉。* @return       : 無*/
void free_irq(unsigned int irq, void *dev);
/** @description : 中斷處理函數* @param-first : 中斷處理函數要響應的中斷號* @param-second: 一個void指針,需要與request_irq函數的dev參數保持一致,用于區分共享中斷的不同設備* @return      : 返回irq_handler_t,是一個枚舉類型*/
irqreturn_t(*irq_handler_t)(int, void*);

?? enable_irq()disable_irq()用于使能和禁止中斷,其中disable_irq()要等當前正在執行的中斷函數處理函數執行完才返回,因此使用者必須保證不會產生新的中斷,并且確保所有已經開始執行的中斷處理函數已經全部退出。

/** @description: 中斷使能與禁止* @param-irq  : 要禁止的中斷號* @return     : 無*/
void enable_irq(unsigned int irq)
void disable_irq(unsigned int irq)

?? 當要立即返回時,可以使用以下函數:

/** @description: 調用后立即返回,不會等待當前中斷處理程序執行完畢* @param-irq  : 要禁止的中斷號* @return     : 無*/
void disable_irq_nosync(unsigned int irq)

?? local_irq_enable() 用于使能當前處理器中斷系統,local_irq_disable() 用于禁止當前處理器中斷系統。

/** @description: 打開和關閉全局中斷* @param      : 無* @return     : 無*/
local_irq_enable()
local_irq_disable()

?? 對于關閉全局中斷但是途中又要打開一會,執行完成后又要保持關閉狀態的話,可以使用如下函數,執行完會將中斷狀態恢復到以前的狀態。

?? local_irq_save 函數用于禁止中斷,并且將中斷狀態保存在 flags 中。local_irq_restore 用于恢復中斷,將中斷到 flags 狀態。

/** @description: 打開和關閉全局中斷* @param-flags: 保存中斷狀態的變量* @return     : 無*/
local_irq_save(flags)
local_irq_restore(flags)

參考資料

[1] 【正點原子】I.MX6U嵌入式Linux驅區動開發指南 第五十一章第十七章

[2] 【操作系統】淺談 Linux 中的中斷機制

[3] Linux內核5. 中斷和中斷處理

[4] Linux_中斷下半部

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/712668.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/712668.shtml
英文地址,請注明出處:http://en.pswp.cn/news/712668.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

初始Tomcat(Tomcat的基礎介紹)

目錄 一、Tomcat的基本介紹 1、Tomcat是什么&#xff1f; 2、Tomcat的配置文件詳解 3、Tomcat的構成組件 4、Tomcat的頂層架構 5、Tomcat的核心功能 6、Tomcat的請求過程 一、Tomcat的基本介紹 1、Tomcat是什么&#xff1f; Tomcat 服務器是一個免費的開放源代碼的Web …

【數據庫管理系統】Mysql 8.0.36入門級安裝

下載地址 官方網址&#xff1a;MySQL 注意事項 建議不要安裝最新版本&#xff0c;一般找mysql5.0或mysql8.0系列版本即可&#xff1b;mysq1官網有.zip和.msi兩種安裝形式&#xff1b;zip是壓縮包&#xff0c;直接解壓縮以后使用的&#xff0c;需要自己配置各種東西&#xff…

912. 排序數組(堆排序)

堆排序&#xff1a; 聲明全局堆長度建堆&#xff08;大頂堆&#xff09;從最后一個元素開始向前遍歷&#xff0c;進行&#xff1a;1. 交換最后元素和堆頂元素&#xff1b;2. 全局堆長度-1&#xff1b;3. 調整大頂堆&#xff08;從第0個位置開始&#xff09; 建堆&#xff1a;…

【遞歸搜索回溯專欄】前言與本專欄介紹

本專欄內容為&#xff1a;遞歸&#xff0c;搜索與回溯算法專欄。 通過本專欄的深入學習&#xff0c;你可以了解并掌握算法。 &#x1f493;博主csdn個人主頁&#xff1a;小小unicorn ?專欄分類&#xff1a;遞歸搜索回溯專欄 &#x1f69a;代碼倉庫&#xff1a;小小unicorn的代…

分享6個解決msvcp110.dll丟失的方法,全面解析msvcp110.dll文件

msvcp110.dll 是一個動態鏈接庫 (DLL) 文件&#xff0c;屬于 Microsoft Visual C 庫的一部分&#xff0c;具體來說是 Microsoft Visual C 2012 版本的運行時組件。這個 DLL 文件包含了在 Windows 環境下運行用 C 編寫的程序所必需的一些函數和資源。當一個應用程序是使用 Visua…

視頻拉流推流技術梳理

概況 視頻的整個流程主要分為推流和拉流 攝像頭場景&#xff1a; 攝像頭捕捉視頻畫面&#xff0c;推流到服務器&#xff0c;服務器分發到CDN&#xff0c; 客戶端從CDN地址拉流&#xff0c;客戶端進行播放 直播場景&#xff1a; 主播通過手機&#xff0c;電腦等客戶端&…

G8-ACGAN理論

本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客 原作者&#xff1a;K同學啊|接輔導、項目定制 我的環境&#xff1a; 1.語言&#xff1a;python3.7 2.編譯器&#xff1a;pycharm 3.深度學習框架Pytorch 1.8.0cu111 一、對比分析 前面的文章介紹了CGAN&#xf…

java基礎(4)注解,集合,

注解 什么是注解&#xff08;Annotation&#xff09;&#xff1f;注解是放在Java源碼的類、方法、字段、參數前的一種特殊“注釋” // this is a component: Resource("hello") public class Hello {Injectint n;PostConstructpublic void hello(Param String name…

經典文獻閱讀之--CamMap(基于SLAM地圖對不共視相機進行外參標定)

0. 簡介 由于多相機之間通常存在有限或無重疊的視場&#xff0c;因此在估計外參相機參數時面臨著一定的挑戰&#xff0c;為了解決這個問題&#xff0c;本文提出了CamMap&#xff1a;一種新穎的6自由度外參標定流程。根據三個操作規則&#xff0c;使一個多相機系統單獨捕捉一些…

【Linux進程】進程狀態(運行阻塞掛起)

目錄 前言 1. 進程狀態 2. 運行狀態 3. 阻塞狀態 4. 掛起狀態 5. Linux中具體的狀態 總結 前言 在Linux操作系統中&#xff0c;進程狀態非常重要&#xff0c;它可以幫助我們了解進程在系統中的運行情況&#xff0c;從而更好地管理和優化系統資源&#xff0c;在Linux系統中&am…

【Python筆記-設計模式】迭代器模式

一、說明 迭代器模式是一種行為設計模式&#xff0c;讓你能在不暴露集合底層表現形式&#xff08;列表、棧和樹等&#xff09;的情況下遍歷集合中所有的元素。 (一) 解決問題 遍歷聚合對象中的元素&#xff0c;而不需要暴露該對象的內部表示 (二) 使用場景 需要對聚合對象…

SpringBoot實現短鏈跳轉

目錄 1.背景介紹 2.短鏈跳轉的意義 3.SpringBoot中的代碼實現 1.建議短鏈-長鏈的數據庫表&#xff1a;t_url_map: 2.映射實體 3.Dao層實現 4.Service層實現 5.Controller層實現 3.結果測試 4.問題 1.背景介紹 短鏈跳轉是一種通過將長鏈接轉換為短鏈接的方式&…

南方電網的能源棋局上,蔚來換電扮演什么角色?

2 月 26 日&#xff0c;南網儲能科技與蔚來能源簽署協議&#xff0c;將充換電站、儲能站、可調負載等聚合資源連接到虛擬電廠平臺&#xff0c;推動換電站作為分布式儲能在虛擬電廠項目上的應用。 蔚來換電站是國內首個智慧微電網型分布式換電設施&#xff0c;可透過換電訂單預…

軟考-系統集成項目管理中級-信息系統建設與設計

本章重點考點 1.信息系統的生命周期 信息系統建設的內容主要包括設備采購、系統集成、軟件開發和運維服務等。信息系統的生命周期可以分為四個階段:立項、開發、運維和消亡。 2.信息系統開發方法 信息系統常用的開發方法有結構化方法、原型法、面向對象方法等 1)結構化方法 …

AI智能分析網關V4:抽煙/打電話/玩手機行為AI算法及場景應用

抽煙、打電話、玩手機是人們在日常生活中常見的行為&#xff0c;但這些行為在某些場合下可能會帶來安全風險。因此&#xff0c;對于這些行為的檢測技術及應用就變得尤為重要。今天來給大家介紹一下TSINGSEE青犀AI智能分析網關V4抽煙/打電話/玩手機檢測算法及其應用場景。 將監控…

java項目打包運行報異常:xxxxx-1.0-SNAPSHOT.jar中沒有主清單屬性

pom.xml中加入這段話即可 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.4</version><executions><execution><…

安泰ATA-7050高壓放大器在微流控細胞分選中的應用

微流控細胞分選是一種用于分離和鑒定生物樣本中特定類型細胞的技術&#xff0c;其原理基于將生物細胞通過微通道進行操縱和區分。微流控細胞分選的原理主要基于流體力學、電氣學、光學和熱力學等多學科的交叉應用。通過設計具有特定尺寸和性質的微通道網絡&#xff0c;可實現對…

RV1126芯片概述

RV1126芯片概述 前言1 主要特性2 詳細參數 前言 1 主要特性 四核 ARM Cortex-A7 and RISC-V MCU250ms快速開機2.0Tops NPU14M ISP with 3幀 HDR支持3個攝像頭同時輸入4K H.264/H.265 視頻編碼和解碼 2 詳細參數

萬人在線直播:構建高效穩定的音視頻架構

萬人在線大型直播音視頻架構解析 隨著網絡技術的發展,大型直播已成為人們生活中不可或缺的一部分。萬人在線直播音視頻架構是實現高清、流暢直播的關鍵。本文將深入探討這一架構的核心組成部分及其運作機制。 直播客戶端作為架構的基石,負責音視頻數據的采集、編碼、推流、…

永磁同步電機無感FOC(龍伯格觀測器)算法技術總結-仿真篇

文章目錄 1、觀測器的引入2、β軸向下的電機觀測器數學模型3、β軸向下的轉子點角度及速度觀測4、Simulink仿真模型搭建4.1模型總覽4.2 Luenberger觀測器模塊4.2.1 I_alpha觀測4.2.2 I_beta觀測4.2.3 e_alpha、e_beta觀測4.2.4 鎖相環 4.3 速度設定4.4 速度觀測結果4.5 電角度觀…