哈哈哈哈哈操欧洲电影,久草网在线,亚洲久久熟女熟妇视频,麻豆精品色,久久福利在线视频,日韩中文字幕的,淫乱毛视频一区,亚洲成人一二三,中文人妻日韩精品电影

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

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

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

RK3576 CPUFreq驅(qū)動(dòng)深度剖析:從原理到實(shí)戰(zhàn)

jf_44130326 ? 來源:Linux1024 ? 2026-04-09 17:13 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

嵌入式Linux性能調(diào)優(yōu)核心戰(zhàn)場(chǎng),從代碼層面徹底吃透DVFS機(jī)制

作為嵌入式Linux開發(fā)者,你是否只停留在echo performance > scaling_governor的表層操作?當(dāng)遇到頻率切換延遲高、電壓調(diào)節(jié)失敗、多核異構(gòu)頻率協(xié)同等問題時(shí),是否束手無策?

今天這篇文章,將逐行剖析RK3576平臺(tái)的cpufreq實(shí)現(xiàn),從源碼層面拆解Linux內(nèi)核DVFS(動(dòng)態(tài)電壓頻率調(diào)節(jié))的每一個(gè)細(xì)節(jié),帶你從會(huì)用精通,解決實(shí)際開發(fā)中的核心痛點(diǎn)。

一、為什么要深入cpufreq源碼?

嵌入式Linux開發(fā)中,cpufreq是性能與功耗平衡的核心,但這些問題往往讓開發(fā)者卡殼:

?頻率切換延遲過高,如何優(yōu)化?

?電壓調(diào)節(jié)失敗,如何定位?

?多核異構(gòu)場(chǎng)景下,頻率如何協(xié)同?

?自定義調(diào)速器,如何接入框架?

只有深入源碼,才能真正掌握DVFS的底層邏輯,而非停留在調(diào)參數(shù)的表面操作。

二、整體架構(gòu):代碼視角的分層設(shè)計(jì)

2.1文件組織與模塊依賴

cpufreq驅(qū)動(dòng)的代碼分布清晰,核心文件各司其職:

drivers/cpufreq/├── cpufreq.c        # 核心框架:策略管理、通知鏈、sysfs├── cpufreq-dt.c      # DT 通用驅(qū)動(dòng):OPP 解析、時(shí)鐘操作├── cpufreq-dt.h      # DT 驅(qū)動(dòng)接口定義├── rockchip-cpufreq.c   # RK 平臺(tái)驅(qū)動(dòng):SoC 特性、DVFS 鎖、監(jiān)控├── rockchip-cpufreq.h   # RK 驅(qū)動(dòng)導(dǎo)出接口├── cpufreq_governor.c   # 調(diào)速器公共框架├── cpufreq_governor.h   # 調(diào)速器數(shù)據(jù)結(jié)構(gòu)├── cpufreq_interactive.c  # Interactive 調(diào)速器實(shí)現(xiàn)├── cpufreq_ondemand.c   # Ondemand 調(diào)速器實(shí)現(xiàn)├── freq_table.c      # 頻率表輔助函數(shù)└── cpufreq_stats.c     # 統(tǒng)計(jì)信息模塊

2.2核心結(jié)構(gòu)體關(guān)系(代碼定義)

cpufreq的核心邏輯圍繞兩個(gè)結(jié)構(gòu)體展開,是理解整個(gè)框架的關(guān)鍵:

// include/linux/cpufreq.hstructcpufreq_policy{ cpumask_var_t     cpus;     // 本策略管理的 CPU 掩碼 cpumask_var_t     related_cpus; // 硬件相關(guān)的 CPU(共享時(shí)鐘) unsignedint      min;      // 用戶設(shè)置的最小頻率 unsignedint      max;      // 用戶設(shè)置的最大頻率 unsignedint      cur;      // 當(dāng)前頻率(kHz) structcpufreq_governor*governor;   // 當(dāng)前調(diào)速器 void          *governor_data;// 調(diào)速器私有數(shù)據(jù) structcpufreq_frequency_table*freq_table;// 頻率表 structcpufreq_stats  *stats;    // 統(tǒng)計(jì)信息 structkobject     kobj;     // sysfs 對(duì)象 void          *driver_data; // 驅(qū)動(dòng)私有數(shù)據(jù) // ... 更多字段};structcpufreq_driver{ char      name[CPUFREQ_NAME_LEN]; unsignedint  flags;
 /* 必須實(shí)現(xiàn)的回調(diào) */ int(*target_index)(structcpufreq_policy *policy,unsignedintindex); unsignedint(*get)(unsignedintcpu);
 /* 可選回調(diào) */ int(*init)(structcpufreq_policy *policy); int(*exit)(structcpufreq_policy *policy); int(*online)(structcpufreq_policy *policy); int(*offline)(structcpufreq_policy *policy); // ...};

腦圖:RK3576 CPUFreq核心架構(gòu)

wKgZPGnRtT2AGcPQAAGnAiZaL38464.png

三、初始化流程:從模塊加載到頻率就緒

RK3576cpufreq初始化是先集群初始化,再注冊(cè)驅(qū)動(dòng)的邏輯,核心分為三步:

3.1驅(qū)動(dòng)入口:rockchip_cpufreq_driver_init

這是整個(gè)RK平臺(tái)cpufreq的入口函數(shù),核心邏輯是遍歷CPU集群、初始化集群信息、注冊(cè)通知鏈和平臺(tái)設(shè)備:

// drivers/cpufreq/rockchip-cpufreq.cstaticint__initrockchip_cpufreq_driver_init(void){ structcluster_info *cluster, *pos; structcpufreq_dt_platform_data pdata = {0}; intcpu, ret; boolis_opp_shared_cpu_bus =false; /* 遍歷所有可能的 CPU,為每個(gè) cluster 初始化 */  for_each_possible_cpu(cpu) {    cluster = rockchip_cluster_info_lookup(cpu);   if(cluster)     continue; // 已初始化過    cluster = kzalloc(sizeof(*cluster), GFP_KERNEL);   if(!cluster) {      ret = -ENOMEM;     gotorelease_cluster_info;    }   /* 核心初始化:解析 OPP、獲取 regulator、設(shè)置 SoC 信息 */    ret = rockchip_cpufreq_cluster_init(cpu, cluster);   if(ret) {      pr_err("Failed to initialize dvfs info cpu%dn", cpu);     gotorelease_cluster_info;    }
    list_add(&cluster->list_head, &cluster_info_list);   if(cluster->is_opp_shared_cpu_bus)      is_opp_shared_cpu_bus =true;  } /* 設(shè)置平臺(tái)數(shù)據(jù) */  pdata.have_governor_per_policy =true;  pdata.suspend = rockchip_cpufreq_suspend; /* 注冊(cè) cpufreq 通知鏈 */  ret = cpufreq_register_notifier(&rockchip_cpufreq_notifier_block,                  CPUFREQ_POLICY_NOTIFIER); if(ret) {    pr_err("failed to register cpufreq notifiern");   gotorelease_cluster_info;  } /* 如果存在 OPP 共享總線,注冊(cè) transition 通知器 */ if(is_opp_shared_cpu_bus) {    ret = cpufreq_register_notifier(&rockchip_cpufreq_transition_notifier_block,                    CPUFREQ_TRANSITION_NOTIFIER);   // ...  } /* 注冊(cè) panic 通知器,用于調(diào)試 */  ret = atomic_notifier_chain_register(&panic_notifier_list,                    &rockchip_cpufreq_panic_notifier_block); /* 注冊(cè) platform_device,觸發(fā) cpufreq-dt 驅(qū)動(dòng) probe */ returnPTR_ERR_OR_ZERO(platform_device_register_data(NULL,"cpufreq-dt",       -1, (void*)&pdata,sizeof(structcpufreq_dt_platform_data)));}module_init(rockchip_cpufreq_driver_init);// drivers/cpufreq/rockchip-cpufreq.cstaticint__initrockchip_cpufreq_driver_init(void){ structcluster_info *cluster, *pos; structcpufreq_dt_platform_data pdata = {0}; intcpu, ret; boolis_opp_shared_cpu_bus =false; /* 遍歷所有可能的 CPU,為每個(gè) cluster 初始化 */  for_each_possible_cpu(cpu) {    cluster = rockchip_cluster_info_lookup(cpu);   if(cluster)     continue; // 已初始化過    cluster = kzalloc(sizeof(*cluster), GFP_KERNEL);   if(!cluster) {      ret = -ENOMEM;     gotorelease_cluster_info;    }   /* 核心初始化:解析 OPP、獲取 regulator、設(shè)置 SoC 信息 */    ret = rockchip_cpufreq_cluster_init(cpu, cluster);   if(ret) {      pr_err("Failed to initialize dvfs info cpu%dn", cpu);     gotorelease_cluster_info;    }
    list_add(&cluster->list_head, &cluster_info_list);   if(cluster->is_opp_shared_cpu_bus)      is_opp_shared_cpu_bus =true;  } /* 設(shè)置平臺(tái)數(shù)據(jù) */  pdata.have_governor_per_policy =true;  pdata.suspend = rockchip_cpufreq_suspend; /* 注冊(cè) cpufreq 通知鏈 */  ret = cpufreq_register_notifier(&rockchip_cpufreq_notifier_block,                  CPUFREQ_POLICY_NOTIFIER); if(ret) {    pr_err("failed to register cpufreq notifiern");   gotorelease_cluster_info;  } /* 如果存在 OPP 共享總線,注冊(cè) transition 通知器 */ if(is_opp_shared_cpu_bus) {    ret = cpufreq_register_notifier(&rockchip_cpufreq_transition_notifier_block,                    CPUFREQ_TRANSITION_NOTIFIER);   // ...  } /* 注冊(cè) panic 通知器,用于調(diào)試 */  ret = atomic_notifier_chain_register(&panic_notifier_list,                    &rockchip_cpufreq_panic_notifier_block); /* 注冊(cè) platform_device,觸發(fā) cpufreq-dt 驅(qū)動(dòng) probe */ returnPTR_ERR_OR_ZERO(platform_device_register_data(NULL,"cpufreq-dt",       -1, (void*)&pdata,sizeof(structcpufreq_dt_platform_data)));}module_init(rockchip_cpufreq_driver_init);

3.2 Cluster初始化:rockchip_cpufreq_cluster_init

每個(gè)CPU集群(大核/小核)的初始化核心是解析OPP表、獲取電壓調(diào)節(jié)器、讀取SoC特有信息:

Cstaticintrockchip_cpufreq_cluster_init(intcpu,structcluster_info *cluster){  structrockchip_opp_info*opp_info = &cluster->opp_info;  structdevice_node*np;  structdevice*dev;  char*reg_name;  intret =0;  u32 freq =0;  dev =get_cpu_device(cpu);  if(!dev)    return-ENODEV;  /* 從 CPU 節(jié)點(diǎn)獲取 operating-points-v2 phandle */  np =of_parse_phandle(dev->of_node,"operating-points-v2",0);  if(!np) {    dev_warn(dev,"OPP-v2 not supportedn");    return-ENOENT;  }  /* 獲取共享 OPP 的 CPU 掩碼(大核/小核 cluster) */  ret =dev_pm_opp_of_get_sharing_cpus(dev, &cluster->cpus);  if(ret) {    dev_err(dev,"Failed to get sharing cpusn");    of_node_put(np);    returnret;  }  /* 檢查是否共享 DSU/CCI 總線 OPP */ if(of_property_read_bool(np,"rockchip,opp-shared-dsu") ||    of_property_read_bool(np,"rockchip,opp-shared-cci"))    cluster->is_opp_shared_cpu_bus =true;  /* 讀取 CPU 到總線頻率的百分比 */ of_property_read_u32(np,"rockchip,cpu-freq-percent",             &cluster->cpu_freq_percent);  /* 讀取空閑閾值頻率 */ if(!of_property_read_u32(np,"rockchip,idle-threshold-freq", &freq))    cluster->idle_threshold_freq = freq;  of_node_put(np);  /* 確定 regulator 名稱 */ if(of_find_property(dev->of_node,"cpu-supply",NULL))    reg_name ="cpu";  elseif(of_find_property(dev->of_node,"cpu0-supply",NULL))    reg_name ="cpu0";  else   return-ENOENT;  /* 獲取 SoC 特定的 OPP 數(shù)據(jù)處理函數(shù) */ rockchip_get_opp_data(rockchip_cpufreq_of_match, opp_info);  /* 初始化 OPP 信息:讀取 nvmem、設(shè)置 supported_hw */  ret =rockchip_init_opp_info(dev, opp_info,NULL, reg_name);  if(ret)    dev_err(dev,"failed to init opp infon");  returnret;}

3.3 RK3576特有的SoC信息讀取

RK3576不同版本(M/J/S)的頻率/電壓支持不同,核心是從nvmem讀取芯片規(guī)格:

staticintrk3576_cpu_get_soc_info(structdevice *dev,structdevice_node *np,                 int*bin,int*process){ intret =0;  u8 spec =0, test_version =0; if(!bin)   return0; /* 從 nvmem 讀取芯片規(guī)格序列號(hào) */ if(of_property_match_string(np,"nvmem-cell-names",                "specification_serial_number") >=0) {    ret = rockchip_nvmem_cell_read_u8(np,                    "specification_serial_number",                     &spec);   if(ret) {      dev_err(dev,"Failed to get specification_serial_numbern");     returnret;    }  } /* 讀取測(cè)試版本 */ if(of_property_match_string(np,"nvmem-cell-names","test_version") >=0) {    ret = rockchip_nvmem_cell_read_u8(np,"test_version", &test_version);   if(ret) {      dev_err(dev,"Failed to get test_versionn");     returnret;    }  } /* 根據(jù) spec 值判斷芯片型號(hào) */ if(spec ==0xd) {    *bin =1; /* RK3576M */  }elseif(spec ==0xa) {    *bin =2; /* RK3576J */  }elseif(spec ==0x13) {   if(test_version ==0) {      *bin =3; /* RK3576S */    }else{      *bin =0;      dev_info(dev,"bin=%d (3)n", *bin);     return0;    }  } if(*bin 0)    *bin =0;  dev_info(dev,"bin=%dn", *bin); returnret;}

流程圖:RK3576 CPUFreq初始化流程

st=>start: 模塊加載(rockchip_cpufreq_driver_init)op1=>operation: 遍歷所有CPUop2=>operation: 查找/創(chuàng)建cluster_infoop3=>operation: rockchip_cpufreq_cluster_initop4=>operation: 解析OPP-v2節(jié)點(diǎn)op5=>operation: 獲取共享CPU掩碼/總線信息op6=>operation: 讀取SoC信息(nvmem)op7=>operation: 注冊(cè)策略/轉(zhuǎn)換通知鏈op8=>operation: 注冊(cè)cpufreq-dt平臺(tái)設(shè)備e=>end: 觸發(fā)cpufreq-dt probe,初始化完成st->op1->op2->op3->op4->op5->op6->op7->op8->e

四、頻率調(diào)整核心:從Governor到硬件

頻率調(diào)整是cpufreq的核心流程,完整鏈路是:調(diào)速器決策核心層處理驅(qū)動(dòng)層執(zhí)行→ OPP子系統(tǒng)硬件(時(shí)鐘/電壓)

4.1調(diào)速器決策:interactive為例

interactive是嵌入式場(chǎng)景最常用的調(diào)速器,核心是按需快速升頻,緩慢降頻,關(guān)鍵邏輯在負(fù)載計(jì)算和頻率評(píng)估:

// drivers/cpufreq/cpufreq_interactive.c/* 核心數(shù)據(jù)結(jié)構(gòu) */structinteractive_cpu{ structupdate_util_dataupdate_util;  // 注冊(cè)到調(diào)度器的鉤子 structinteractive_policy*ipolicy;
 structirq_workirq_work;       // 中斷上下文工作  u64 last_sample_time; boolwork_in_progress;
 /* 負(fù)載計(jì)算相關(guān) */ spinlock_tload_lock;  u64 time_in_idle;  u64 time_in_idle_timestamp;  u64 cputime_speedadj;         // 加權(quán) CPU 時(shí)間
 /* 頻率控制 */ spinlock_ttarget_freq_lock; unsignedinttarget_freq; unsignedintfloor_freq;        // 最低允許頻率  u64 pol_floor_val_time;        // 策略級(jí) floor 時(shí)間  u64 loc_floor_val_time;        // CPU 級(jí) floor 時(shí)間 // ...};/* 調(diào)度器回調(diào):每次 CPU 狀態(tài)更新時(shí)調(diào)用 */staticvoiddbs_update_util_handler(structupdate_util_data *data, u64 time,                 unsignedintflags){ structinteractive_cpu*icpu =container_of(data,structinteractive_cpu, update_util); structinteractive_policy*ipolicy = icpu->ipolicy; structinteractive_tunables*tunables = ipolicy->tunables;  u64 delta_ns, lst; /* 檢查是否可以更新 */ if(!cpufreq_this_cpu_can_update(ipolicy->policy))   return; /* 避免重復(fù)工作 */ if(icpu->work_in_progress)   return; /* 檢查采樣間隔 */  lst =READ_ONCE(icpu->last_sample_time);  delta_ns = time - lst; if((s64)delta_ns < tunables->sampling_rate * NSEC_PER_USEC)   return; /* 提交 irq_work,在中斷上下文執(zhí)行 */  icpu->last_sample_time = time;  icpu->work_in_progress =true; irq_work_queue(&icpu->irq_work);}/* 實(shí)際頻率評(píng)估函數(shù) */staticvoideval_target_freq(structinteractive_cpu *icpu){ structinteractive_tunables*tunables = icpu->ipolicy->tunables; structcpufreq_policy*policy = icpu->ipolicy->policy;  u64 cputime_speedadj, now, max_fvtime; unsignedintnew_freq, loadadjfreq, delta_time; unsignedlongflags; intcpu_load; /* 計(jì)算 CPU 負(fù)載 */ spin_lock_irqsave(&icpu->load_lock, flags);  now =update_load(icpu,smp_processor_id());  delta_time = (unsignedint)(now - icpu->cputime_speedadj_timestamp);  cputime_speedadj = icpu->cputime_speedadj; spin_unlock_irqrestore(&icpu->load_lock, flags); if(!delta_time)   return; /* 計(jì)算負(fù)載百分比 */  cpu_load = (unsignedint)(100* cputime_speedadj / delta_time) / policy->cur; spin_lock_irqsave(&icpu->target_freq_lock, flags); /* 根據(jù)負(fù)載選擇目標(biāo)頻率 */  loadadjfreq = cpu_load * policy->cur;
 if(cpu_load >= tunables->go_hispeed_load) {   /* 高負(fù)載:進(jìn)入 hispeed_freq */   if(policy->cur < tunables->hispeed_freq) {      new_freq = tunables->hispeed_freq;    }else{      new_freq =choose_freq(icpu, loadadjfreq);
     /* 檢查 above_hispeed_delay */     if(now - max_fvtime freq_to_above_hispeed_delay(tunables, new_freq))        new_freq =max(new_freq, tunables->hispeed_freq);    }  }else{   /* 低負(fù)載:按比例降頻 */    new_freq =choose_freq(icpu, loadadjfreq);  } /* 應(yīng)用 floor 約束 */ if(new_freq < icpu->floor_freq) {   if(now - icpu->pol_floor_val_time < tunables->min_sample_time)      new_freq = icpu->floor_freq;  } /* 限制在策略范圍內(nèi) */  new_freq =max(new_freq, policy->min);  new_freq =min(new_freq, policy->max); /* 提交頻率變更 */ if(new_freq != policy->cur) {    icpu->target_freq = new_freq;   spin_lock(&speedchange_cpumask_lock);   cpumask_set_cpu(smp_processor_id(), &speedchange_cpumask);   spin_unlock(&speedchange_cpumask_lock);   wake_up_process(speedchange_task); // 喚醒內(nèi)核線程執(zhí)行變更  } spin_unlock_irqrestore(&icpu->target_freq_lock, flags);}

4.2頻率選擇算法choose_freq

interactive調(diào)速器的核心算法,用二分查找思想找到滿足負(fù)載的最低頻率:

/** 選擇滿足目標(biāo)負(fù)載的最低頻率* 采用二分查找思想,在頻率表中尋找最優(yōu)解*/staticunsignedintchoose_freq(structinteractive_cpu *icpu,               unsignedintloadadjfreq){ structcpufreq_policy*policy = icpu->ipolicy->policy; structcpufreq_frequency_table*freq_table = policy->freq_table; unsignedintprevfreq, freqmin =0, freqmax = UINT_MAX, tl; unsignedintfreq = policy->cur; intindex; do{    prevfreq = freq;
   /* 獲取當(dāng)前頻率的目標(biāo)負(fù)載 */    tl =freq_to_targetload(icpu->ipolicy->tunables, freq);   /*    * 查找滿足 loadadjfreq / tl <= freq 的最低頻率    * 即:freq >= loadadjfreq / tl    */    index =cpufreq_frequency_table_target(policy, loadadjfreq / tl,                       CPUFREQ_RELATION_L);    freq = freq_table[index].frequency;   if(freq > prevfreq) {     /* 頻率上升:記錄最小值 */      freqmin = prevfreq;     if(freq >= freqmax) {       /* 超過上限,回退 */        index =cpufreq_frequency_table_target(policy, freqmax -1,                           CPUFREQ_RELATION_H);        freq = freq_table[index].frequency;       if(freq == freqmin)         break;      }    }elseif(freq < prevfreq) {     /* 頻率下降:記錄最大值 */      freqmax = prevfreq;     if(freq <= freqmin) {       /* 低于下限,回退 */        index =cpufreq_frequency_table_target(policy, freqmin +1,                           CPUFREQ_RELATION_L);        freq = freq_table[index].frequency;       if(freq == freqmax)         break;      }    }  }while(freq != prevfreq); returnfreq;}

4.3核心層頻率切換:cpufreq_core

核心層負(fù)責(zé)頻率切換的同步、通知和狀態(tài)管理,保證線程安全:

// drivers/cpufreq/cpufreq.c/* 開始頻率轉(zhuǎn)換 */voidcpufreq_freq_transition_begin(structcpufreq_policy *policy,                 structcpufreq_freqs *freqs){ /* 防止重復(fù)調(diào)用導(dǎo)致死鎖 */ WARN_ON(!(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION)      && current == policy->transition_task);wait: /* 等待前一次轉(zhuǎn)換完成 */ wait_event(policy->transition_wait, !policy->transition_ongoing); spin_lock(&policy->transition_lock); if(unlikely(policy->transition_ongoing)) {   spin_unlock(&policy->transition_lock);   gotowait;  }  policy->transition_ongoing =true;  policy->transition_task = current; spin_unlock(&policy->transition_lock); /* 發(fā)送 PRECHANGE 通知 */ cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);}/* 頻率轉(zhuǎn)換通知 */staticvoidcpufreq_notify_transition(structcpufreq_policy *policy,                  structcpufreq_freqs *freqs,                  unsignedintstate){ intcpu;  freqs->policy = policy;  freqs->flags = cpufreq_driver->flags; switch(state) { caseCPUFREQ_PRECHANGE:   /* 同步 old frequency */   if(policy->cur && policy->cur != freqs->old) {      freqs->old = policy->cur;    }   /* 調(diào)用 transition notifier 鏈 */   srcu_notifier_call_chain(&cpufreq_transition_notifier_list,                CPUFREQ_PRECHANGE, freqs);   /* 調(diào)整 loops_per_jiffy */   adjust_jiffies(CPUFREQ_PRECHANGE, freqs);   break; caseCPUFREQ_POSTCHANGE:   adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);   /* 記錄 tracepoint */    for_each_cpu(cpu, policy->cpus)     trace_cpu_frequency(freqs->new, cpu);   /* 調(diào)用 transition notifier 鏈 */   srcu_notifier_call_chain(&cpufreq_transition_notifier_list,                CPUFREQ_POSTCHANGE, freqs);   /* 更新統(tǒng)計(jì) */   cpufreq_stats_record_transition(policy, freqs->new);    policy->cur = freqs->new;  }}/* 結(jié)束頻率轉(zhuǎn)換 */voidcpufreq_freq_transition_end(structcpufreq_policy *policy,                structcpufreq_freqs *freqs,                inttransition_failed){ cpufreq_notify_post_transition(policy, freqs, transition_failed); /* 更新頻率縮放比例(用于調(diào)度器) */ arch_set_freq_scale(policy->related_cpus,            policy->cur,            policy->cpuinfo.max_freq); spin_lock(&policy->transition_lock);  policy->transition_ongoing =false;  policy->transition_task =NULL; spin_unlock(&policy->transition_lock); wake_up(&policy->transition_wait);}

4.4驅(qū)動(dòng)層實(shí)現(xiàn):cpufreq-dt

DT驅(qū)動(dòng)是通用層,對(duì)接核心層和平臺(tái)層,核心是頻率/電壓的實(shí)際設(shè)置:

// drivers/cpufreq/cpufreq-dt.c/* 設(shè)置目標(biāo)頻率 */staticintset_target(structcpufreq_policy *policy,unsignedintindex){ structprivate_data*priv = policy->driver_data; unsignedlongfreq = policy->freq_table[index].frequency;#ifdefCONFIG_ARCH_ROCKCHIP /* RK 平臺(tái)使用特殊的 OPP 設(shè)置函數(shù) */ returnrockchip_cpufreq_opp_set_rate(priv->cpu_dev, freq *1000);#else returndev_pm_opp_set_rate(priv->cpu_dev, freq *1000);#endif}/* 驅(qū)動(dòng)初始化 */staticintcpufreq_init(structcpufreq_policy *policy){ structprivate_data*priv; structdevice*cpu_dev; structclk*cpu_clk; unsignedinttransition_latency; intret;  priv =cpufreq_dt_find_data(policy->cpu); if(!priv) {   pr_err("failed to find data for cpu%dn", policy->cpu);   return-ENODEV;  }  cpu_dev = priv->cpu_dev; /* 獲取 CPU 時(shí)鐘 */  cpu_clk =clk_get(cpu_dev,NULL); if(IS_ERR(cpu_clk)) {    ret =PTR_ERR(cpu_clk);   dev_err(cpu_dev,"%s: failed to get clk: %dn", __func__, ret);   returnret;  } /* 獲取最大轉(zhuǎn)換延遲 */  transition_latency =dev_pm_opp_get_max_transition_latency(cpu_dev); if(!transition_latency)    transition_latency = CPUFREQ_ETERNAL; /* 填充 policy */ cpumask_copy(policy->cpus, priv->cpus);  policy->driver_data = priv;  policy->clk = cpu_clk;  policy->freq_table = priv->freq_table;  policy->suspend_freq =dev_pm_opp_get_suspend_opp_freq(cpu_dev) /1000;  policy->cpuinfo.transition_latency = transition_latency;  policy->dvfs_possible_from_any_cpu =true; /* 支持 boost 模式 */ if(policy_has_boost_freq(policy)) {    ret =cpufreq_enable_boost_support();   if(ret)     gotoout_clk_put;    cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;  } return0;out_clk_put: clk_put(cpu_clk); returnret;}staticstructcpufreq_driverdt_cpufreq_driver = {  .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |      CPUFREQ_IS_COOLING_DEV,  .verify = cpufreq_generic_frequency_table_verify,  .target_index = set_target,  .get = cpufreq_generic_get,  .init = cpufreq_init,  .exit = cpufreq_exit,  .online = cpufreq_online,  .offline = cpufreq_offline,  .register_em = cpufreq_register_em_with_opp,  .name ="cpufreq-dt",  .attr = cpufreq_dt_attr,  .suspend = cpufreq_generic_suspend,};

4.5 RK平臺(tái)特殊處理:rockchip_cpufreq

RK3576的定制化邏輯,包括DVFS鎖、Read Margin、多路電壓調(diào)節(jié)器:

// drivers/cpufreq/rockchip-cpufreq.c/* RK 平臺(tái)頻率設(shè)置入口 */introckchip_cpufreq_opp_set_rate(structdevice *dev,unsignedlongtarget_freq){ structcluster_info*cluster; structdev_pm_opp*opp; structrockchip_opp_info*opp_info; structdev_pm_opp_supplysupplies[2] = {0}; unsignedlongfreq; intret =0;  cluster =rockchip_cluster_info_lookup(dev->id); if(!cluster)   return-EINVAL;  opp_info = &cluster->opp_info; /* 獲取 DVFS 鎖,防止并發(fā)修改 */ rockchip_opp_dvfs_lock(opp_info);
 /* 調(diào)用 OPP 子系統(tǒng)設(shè)置頻率 */  ret =dev_pm_opp_set_rate(dev, target_freq);
 if(!ret) {    cluster->rate = freq = target_freq;
   /* 查找當(dāng)前 OPP,獲取電壓信息 */    opp =dev_pm_opp_find_freq_ceil(dev, &freq);   if(!IS_ERR(opp)) {     dev_pm_opp_get_supplies(opp, supplies);      cluster->volt = supplies[0].u_volt;     if(opp_info->regulator_count >1)        cluster->mem_volt = supplies[1].u_volt;     dev_pm_opp_put(opp);    }  }
 rockchip_opp_dvfs_unlock(opp_info); returnret;}EXPORT_SYMBOL_GPL(rockchip_cpufreq_opp_set_rate);/* RK3576 Read Margin 設(shè)置 */staticintrk3576_cpu_set_read_margin(structdevice *dev,                  structrockchip_opp_info *opp_info,                   u32 rm){ if(!opp_info->volt_rm_tbl)   return0; if(rm == opp_info->current_rm || rm == UINT_MAX)   return0; dev_dbg(dev,"set rm to %dn", rm);
 /* 通過 GRF 配置 Read Margin */ if(opp_info->grf) {   /* CPU0-3 核心 */   regmap_write(opp_info->grf,0x3c,0x001c0000| (rm <2));   regmap_write(opp_info->grf,0x44,0x001c0000| (rm <2));
   /* 觸發(fā)更新 */   regmap_write(opp_info->grf,0x38,0x00020002);   udelay(1);   regmap_write(opp_info->grf,0x38,0x00020000);  }
 /* CCI 接口 */ if(opp_info->cci_grf)   regmap_write(opp_info->cci_grf,0x54,0x001c0000| (rm <2));  opp_info->current_rm = rm; return0;}/* 多路 regulator 配置 */staticintcpu_opp_config_regulators(structdevice *dev,                  structdev_pm_opp *old_opp,                  structdev_pm_opp *new_opp,                  structregulator **regulators,                  unsignedintcount){ structcluster_info*cluster;  cluster =rockchip_cluster_info_lookup(dev->id); if(!cluster)   return-EINVAL; returnrockchip_opp_config_regulators(dev, old_opp, new_opp, regulators,                     count, &cluster->opp_info);}

流程圖:RK3576頻率調(diào)整完整流程

st=>start: 調(diào)度器觸發(fā)負(fù)載更新op1=>operation: interactive調(diào)速器(eval_target_freq)op2=>operation: 計(jì)算CPU負(fù)載,選擇目標(biāo)頻率op3=>operation: 核心層(cpufreq_freq_transition_begin)op4=>operation: 發(fā)送PRECHANGE通知op5=>operation: 驅(qū)動(dòng)層(set_target)op6=>operation: RK平臺(tái)(rockchip_cpufreq_opp_set_rate)op7=>operation: OPP子系統(tǒng)(dev_pm_opp_set_rate)op8=>operation: 升頻:先升壓后升頻;降頻:先降頻后降壓op9=>operation: 核心層(cpufreq_freq_transition_end)op10=>operation: 發(fā)送POSTCHANGE通知,更新統(tǒng)計(jì)e=>end: 頻率切換完成st->op1->op2->op3->op4->op5->op6->op7->op8->op9->op10->e

五、OPP子系統(tǒng):頻率-電壓表的奧秘

OPPOperating Performance Point)是連接軟件和硬件的關(guān)鍵,定義了頻率-電壓的映射關(guān)系,是DVFS的基礎(chǔ)。

5.1 OPP數(shù)據(jù)結(jié)構(gòu)

// include/linux/pm_opp.hstructdev_pm_opp{ structlist_headnode;
 unsignedlongrate;     // 頻率 (Hz) unsignedlongu_volt;    // 電壓 (uV) unsignedlongu_volt_min;  // 最小電壓 unsignedlongu_volt_max;  // 最大電壓
 structdevice_opp*dev_opp; // 所屬設(shè)備
 /* 支持的條件 */ unsignedlongsupported_hw; // 硬件版本掩碼
 /* 供電信息 */ structopp_supply*supplies; unsignedintsupply_count;
 /* 自定義數(shù)據(jù) */ void*priv;};structdevice_opp{ structlist_headnode; structdevice*dev; structsrcu_notifier_headsrcu_head; structlist_headopp_list;
 structclk*clk; structregulator**regulators; unsignedintregulator_count;
 structopp_table*opp_table;};

5.2 Device Tree OPP定義

RK3576OPP表在DTS中定義,不同芯片版本支持不同頻率:

// arch/arm64/boot/dts/rockchip/rk3576.dtsicpu0_opp_table:opp-table-0{  compatible ="operating-points-v2";  opp-shared;
 /* 408 MHz */  opp-408000000{    opp-hz =/bits/64<408000000>;    opp-microvolt = <800000>;    clock-latency-ns = <40000>;  };
 /* 600 MHz */  opp-600000000{    opp-hz =/bits/64<600000000>;    opp-microvolt = <825000>;  };
 /* 816 MHz */  opp-816000000{    opp-hz =/bits/64<816000000>;    opp-microvolt = <850000>;  };
 /* 1.2 GHz */  opp-1200000000{    opp-hz =/bits/64<1200000000>;    opp-microvolt = <925000>;  };
 /* 1.608 GHz - 僅支持特定芯片版本 */  opp-1608000000{    opp-hz =/bits/64<1608000000>;    opp-microvolt = <1100000>;    opp-supported-hw = <0x10x1>; //bin=0, volt_sel=0  };
 /* 1.8 GHz - 更高規(guī)格芯片 */  opp-1800000000{    opp-hz =/bits/64<1800000000>;    opp-microvolt = <1175000>;    opp-supported-hw = <0x10x3>; //bin=0, volt_sel=0,1,2  };};

5.3 OPP查找與設(shè)置流程

OPP子系統(tǒng)的核心函數(shù),負(fù)責(zé)頻率/電壓的實(shí)際設(shè)置:

// drivers/opp/core.c/*** dev_pm_opp_set_rate() - 設(shè)置設(shè)備到指定頻率* @dev: 設(shè)備* @target_freq: 目標(biāo)頻率 (Hz)** 1. 查找匹配的 OPP* 2. 設(shè)置 regulator 電壓* 3. 設(shè)置時(shí)鐘頻率*/intdev_pm_opp_set_rate(structdevice *dev,unsignedlongtarget_freq){ structdevice_opp*dev_opp; structdev_pm_opp*opp; structclk*clk; unsignedlongold_freq, new_freq; intret;  dev_opp = _find_device_opp(dev); if(IS_ERR(dev_opp))   returnPTR_ERR(dev_opp);  clk = dev_opp->clk;  old_freq =clk_get_rate(clk); /* 查找目標(biāo)頻率對(duì)應(yīng)的 OPP */  opp = _find_freq_ceil(dev_opp, &target_freq); if(IS_ERR(opp)) {    ret =PTR_ERR(opp);   gotoput_opp;  }  new_freq = opp->rate; /* 如果頻率相同,只更新電壓 */ if(new_freq == old_freq) {    ret = _set_opp_voltage(dev, dev_opp, opp);   gotoput_opp;  } /* 升頻:先升壓,后升頻 */ if(new_freq > old_freq) {    ret = _set_opp_voltage(dev, dev_opp, opp);   if(ret)     gotoput_opp;
    ret =clk_set_rate(clk, new_freq);   if(ret) {     /* 回滾電壓 */      _set_opp_voltage(dev, dev_opp, _find_freq_floor(dev_opp, &old_freq));    }  }else{   /* 降頻:先降頻,后降壓 */    ret =clk_set_rate(clk, new_freq);   if(ret)     gotoput_opp;
    _set_opp_voltage(dev, dev_opp, opp);  }put_opp: dev_pm_opp_put(opp); returnret;}

流程圖:OPP頻率-電壓設(shè)置流程

st=>start: 調(diào)用dev_pm_opp_set_rateop1=>operation: 查找設(shè)備對(duì)應(yīng)的device_oppop2=>operation: 獲取當(dāng)前時(shí)鐘頻率(old_freq)op3=>operation: 查找目標(biāo)頻率的OPP(ceil)op4=>operation: 判斷new_freq == old_freq?op5=>operation: 僅更新電壓(_set_opp_voltage)op6=>operation: new_freq > old_freq?op7=>operation: 先升壓,后升頻op8=>operation: 升頻失敗,回滾電壓op9=>operation: 先降頻,后降壓e=>end: 返回設(shè)置結(jié)果st->op1->op2->op3->op4op4(yes)->op5->eop4(no)->op6op6(yes)->op7->eop7(no)->op8->eop6(no)->op9->e

六、通知鏈機(jī)制:頻率變更的廣播系統(tǒng)

cpufreq的通知鏈?zhǔn)?/span>事件廣播機(jī)制,允許其他子系統(tǒng)(如溫控、功耗管理)監(jiān)聽頻率變更事件,是內(nèi)核模塊化設(shè)計(jì)的典型體現(xiàn)。

6.1兩種通知鏈

// drivers/cpufreq/cpufreq.c/* 策略通知鏈:策略創(chuàng)建/銷毀時(shí)調(diào)用 */staticBLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);/* 轉(zhuǎn)換通知鏈:頻率變更前后調(diào)用 */SRCU_NOTIFIER_HEAD_STATIC(cpufreq_transition_notifier_list);

6.2 RK平臺(tái)的通知器注冊(cè)

RK3576通過通知鏈實(shí)現(xiàn)頻率-空閑狀態(tài)聯(lián)動(dòng)、總線QoS約束:

// drivers/cpufreq/rockchip-cpufreq.c/* 策略通知器:處理監(jiān)控注冊(cè)和總線 QoS */staticintrockchip_cpufreq_notifier(structnotifier_block *nb,                  unsignedlongevent,void*data){ structcpufreq_policy *policy = data; structcluster_info *cluster;  cluster = rockchip_cluster_info_lookup(policy->cpu); if(!cluster)   returnNOTIFY_BAD; switch(event) { caseCPUFREQ_CREATE_POLICY:   /* 注冊(cè)系統(tǒng)監(jiān)控 */   if(rockchip_cpufreq_add_monitor(cluster, policy))     returnNOTIFY_BAD;
   /* 添加總線頻率 QoS 約束 */   if(rockchip_cpufreq_add_bus_qos_req(cluster, policy))     returnNOTIFY_BAD;   break; caseCPUFREQ_REMOVE_POLICY:    rockchip_cpufreq_remove_monitor(cluster);    rockchip_cpufreq_remove_bus_qos(cluster);   break;  } returnNOTIFY_OK;}/* 轉(zhuǎn)換通知器:處理空閑狀態(tài) */staticintrockchip_cpufreq_transition_notifier(structnotifier_block *nb,                        unsignedlongevent,void*data){ structcpufreq_freqs *freqs = data; structcpufreq_policy *policy = freqs->policy; structcluster_info *cluster;  cluster = rockchip_cluster_info_lookup(policy->cpu); if(!cluster)   returnNOTIFY_BAD; switch(event) { caseCPUFREQ_PRECHANGE:   /* 高頻時(shí)禁用深層空閑狀態(tài) */   if(cluster->idle_threshold_freq &&      freqs->new>= cluster->idle_threshold_freq &&      !cluster->is_idle_disabled) {      rockchip_cpufreq_idle_state_disable(policy->cpus,1,true);      cluster->is_idle_disabled =true;    }   break; caseCPUFREQ_POSTCHANGE:   /* 低頻時(shí)重新啟用空閑狀態(tài) */   if(cluster->idle_threshold_freq &&      freqs->new< cluster->idle_threshold_freq &&      cluster->is_idle_disabled) {      rockchip_cpufreq_idle_state_disable(policy->cpus,1,false);      cluster->is_idle_disabled =false;    }
   /* 更新總線頻率請(qǐng)求 */    rockchip_cpufreq_update_bus_req(cluster, freqs->new);   break;  } returnNOTIFY_OK;}

6.3使用場(chǎng)景示例

溫控驅(qū)動(dòng)通過通知鏈監(jiān)聽頻率變更,更新熱模型:

/* 溫度管理驅(qū)動(dòng)注冊(cè)通知器 */staticintthermal_cpufreq_notifier(structnotifier_block *nb,                  unsignedlongevent,void*data){ structcpufreq_freqs *freqs = data;
 if(event== CPUFREQ_POSTCHANGE) {   /* 頻率變更后更新熱模型 */    update_thermal_model(freqs->new);  }
 returnNOTIFY_OK;}staticstructnotifier_block thermal_nb = {  .notifier_call = thermal_cpufreq_notifier,};/* 注冊(cè) */cpufreq_register_notifier(&thermal_nb, CPUFREQ_TRANSITION_NOTIFIER);

七、統(tǒng)計(jì)與調(diào)試:洞察系統(tǒng)行為

掌握調(diào)試技巧,才能快速定位頻率調(diào)節(jié)的問題,cpufreq提供了豐富的統(tǒng)計(jì)和調(diào)試接口。

7.1統(tǒng)計(jì)模塊實(shí)現(xiàn)

// drivers/cpufreq/cpufreq_stats.cstructcpufreq_stats{ unsignedinttotal_trans;     // 總切換次數(shù) unsignedlonglonglast_time;   // 上次更新時(shí)間 unsignedintmax_state;      // 最大狀態(tài)數(shù) unsignedintstate_num;      // 實(shí)際狀態(tài)數(shù) unsignedintlast_index;      // 當(dāng)前狀態(tài)索引  u64 *time_in_state;        // 各頻率駐留時(shí)間 unsignedint*freq_table;     // 頻率表 unsignedint*trans_table;     // 切換矩陣};/* 記錄一次頻率切換 */voidcpufreq_stats_record_transition(structcpufreq_policy *policy,                  unsignedintnew_freq){ structcpufreq_stats*stats = policy->stats; intold_index, new_index; if(!stats)   return;  old_index = stats->last_index;  new_index =freq_table_get_index(stats, new_freq); if(old_index ==-1|| new_index ==-1|| old_index == new_index)   return; /* 更新駐留時(shí)間 */ cpufreq_stats_update(stats, stats->last_time);  stats->last_index = new_index;  stats->trans_table[old_index * stats->max_state + new_index]++;  stats->total_trans++;}

7.2調(diào)試技巧

# 1. 查看當(dāng)前頻率和策略cat/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freqcat/sys/devices/system/cpu/cpu0/cpufreq/scaling_governorcat/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freqcat/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq# 2. 查看頻率駐留時(shí)間統(tǒng)計(jì)cat/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state# 輸出格式: 頻率(Hz) 時(shí)間(時(shí)鐘周期)# 408000 1234567# 600000 2345678# ...# 3. 查看頻率切換矩陣cat/sys/devices/system/cpu/cpu0/cpufreq/stats/trans_table# 顯示從每個(gè)頻率切換到其他頻率的次數(shù)# 4. 查看可用頻率和調(diào)速器cat/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequenciescat/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors# 5. 動(dòng)態(tài)切換調(diào)速器echouserspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governorecho1200000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed# 6. 內(nèi)核日志調(diào)試dmesg | grep -i cpufreqdmesg | grep -i"rk3576|rockchip"# 7. 使用 tracepointcd/sys/kernel/debug/tracingecho1 > events/cpufreq/enablecattrace

八、實(shí)戰(zhàn):自定義調(diào)速器開發(fā)

掌握自定義調(diào)速器的開發(fā),才能適配特定場(chǎng)景的性能/功耗需求。

8.1最小調(diào)速器框架

#include#includestaticintmygov_target(structcpufreq_policy *policy,unsignedinttarget_freq,           unsignedintrelation){ /* 簡(jiǎn)單的頻率設(shè)置 */ return__cpufreq_driver_target(policy, target_freq, relation);}staticintmygov_init(structcpufreq_policy *policy){ /* 初始化 */ return0;}staticvoidmygov_exit(structcpufreq_policy *policy){ /* 清理 */}staticstructcpufreq_governormy_governor = {  .name ="mygov",  .target = mygov_target,  .init = mygov_init,  .exit = mygov_exit,  .owner = THIS_MODULE,};staticint__initmygov_init_module(void){ returncpufreq_register_governor(&my_governor);}staticvoid__exitmygov_exit_module(void){ cpufreq_unregister_governor(&my_governor);}module_init(mygov_init_module);module_exit(mygov_exit_module);MODULE_LICENSE("GPL");

8.2基于負(fù)載的調(diào)速器

staticvoidmygov_update(structcpufreq_policy *policy){ unsignedintload =calculate_cpu_load(policy); unsignedintnew_freq; if(load >80) {   /* 高負(fù)載:升頻到最大 */    new_freq = policy->max;  }elseif(load 20) {   /* 低負(fù)載:降頻到最小 */    new_freq = policy->min;  }else{   /* 中等負(fù)載:線性插值 */    new_freq = policy->min + load * (policy->max - policy->min) /100;  }  __cpufreq_driver_target(policy, new_freq, CPUFREQ_RELATION_H);}

腦圖:自定義調(diào)速器開發(fā)

wKgZPGnRtT2AIFMJAAHLeSBcols237.png

九、性能優(yōu)化實(shí)戰(zhàn)

針對(duì)實(shí)際開發(fā)中的痛點(diǎn),優(yōu)化頻率切換延遲、負(fù)載計(jì)算精度。

9.1減少頻率切換延遲

/* 1. 使用 fast frequency switching */staticstructcpufreq_drivermy_driver={  .flags=CPUFREQ_FAST_SWITCHING,  .fast_switch=my_fast_switch, // 原子上下文切換};/* 2. 減少 transition latency */// 在 OPP 表中設(shè)置較小的 clock-latency-nsopp-1200000000{  opp-hz=/bits/64<1200000000>;  clock-latency-ns=<10000>; // 10us,而不是 40us};

9.2優(yōu)化負(fù)載計(jì)算

/* 使用 PELT 信號(hào)代替 idle time */#includestaticunsignedintget_pelt_load(structcpufreq_policy *policy){ unsignedintcpu = policy->cpu; structrq*rq =cpu_rq(cpu);
 /* PELT (Per-Entity Load Tracking) 是調(diào)度器內(nèi)部的負(fù)載跟蹤機(jī)制 */ returnrq->cfs.avg.util_avg; // 0 ~ 1024}

腦圖:性能優(yōu)化實(shí)戰(zhàn)

wKgZPGnRtT2ATjvXAAHk74WONG8190.png

十、總結(jié)與延伸

10.1核心要點(diǎn)回顧

1.分層架構(gòu)governor → core → driver → OPP → clk/regulator

2.線程安全transition_lock、DVFS locknotifier chain

3.硬件抽象OPP表統(tǒng)一頻率-電壓關(guān)系

4.平臺(tái)特性RK3576Read Margin、多路regulator

10.2延伸閱讀

?Documentation/cpu-freq/-內(nèi)核文檔

?drivers/opp/- OPP子系統(tǒng)實(shí)現(xiàn)

?drivers/cpufreq/cpufreq_schedutil.c-最新schedutil調(diào)速器

?include/linux/cpufreq.h-完整API定義

10.3調(diào)試checklist

dmesg | grep cpufreq查看初始化日志

cat scaling_available_frequencies確認(rèn)頻率表

cat time_in_state確認(rèn)頻率切換正常

trace-cmd record -e cpufreq抓取切換事件

檢查regulator是否支持動(dòng)態(tài)電壓調(diào)節(jié)

寫在最后

cpufreqLinux內(nèi)核中最接近硬件的子系統(tǒng)之一,理解它不僅能幫你優(yōu)化系統(tǒng)性能,更能深入理解內(nèi)核的設(shè)備模型、電源管理和并發(fā)控制機(jī)制。

聲明:本文內(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)注

    5208

    文章

    20603

    瀏覽量

    336503
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11803

    瀏覽量

    219455
  • rk3576
    +關(guān)注

    關(guān)注

    1

    文章

    288

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

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

    基于RK3576開發(fā)板的PWN使用說明

    RK3576開發(fā)板使用PWN教程及Demo
    的頭像 發(fā)表于 05-07 14:07 ?2450次閱讀
    基于<b class='flag-5'>RK3576</b>開發(fā)板的PWN使用說明

    【米爾RK3576開發(fā)板評(píng)測(cè)】+項(xiàng)目名稱【米爾RK3576開發(fā)板評(píng)測(cè)】一個(gè)視頻和你共同認(rèn)識(shí)一下米爾RK3576開發(fā)板

    TOPS超強(qiáng)算力,8核CPU賦能AI 瑞芯微RK3576搭載了四核A72與四核A53處理器,主頻高達(dá)2.2GHz,確保了系統(tǒng)的高效運(yùn)行和強(qiáng)大的計(jì)算能力。RK3576集成了6TOPS的NPU,支持多種深度
    發(fā)表于 12-18 20:50

    米爾RK3576RK3588怎么選?-看這篇就夠了

    在中國(guó)半導(dǎo)體產(chǎn)業(yè)的版圖中,瑞芯微作為國(guó)內(nèi)SoC芯片領(lǐng)跑者,憑借其在處理器芯片設(shè)計(jì)領(lǐng)域的深厚積累和持續(xù)創(chuàng)新,推出很多智能應(yīng)用處理器芯片,在嵌入式系統(tǒng)領(lǐng)域得到大規(guī)模的應(yīng)用。RK3588和RK3576系列
    發(fā)表于 12-27 11:44

    性能到成本,深度剖析 RK3588 與 RK3576 怎么選

    在中國(guó)半導(dǎo)體產(chǎn)業(yè)的版圖中,瑞芯微作為國(guó)內(nèi)SoC芯片領(lǐng)跑者,憑借其在處理器芯片設(shè)計(jì)領(lǐng)域的深厚積累和持續(xù)創(chuàng)新,推出很多智能應(yīng)用處理器芯片,在嵌入式系統(tǒng)領(lǐng)域得到大規(guī)模的應(yīng)用。RK3588和RK3576系列
    發(fā)表于 02-09 09:10

    RK3576 vs RK3588:為何越來越多的開發(fā)者轉(zhuǎn)向RK3576?

    的成本結(jié)構(gòu)以及針對(duì)特定場(chǎng)景的深度優(yōu)化,正在成為中高端市場(chǎng)的熱門選擇。那么,RK3576 究竟有哪些優(yōu)勢(shì)?它是否真的能替代 RK3588?我們來做一個(gè)全面對(duì)比。 1. 核心性能對(duì)比:夠用且高效[td
    發(fā)表于 05-30 08:46

    Mpp支持RK3576

    想問下,https://github.com/rockchip-linux/mpp這里面支持RK3576么,看介紹沒有提到說支持RK3576 目前是買了個(gè)rk3576的機(jī)頂盒,搭載了安卓14,想做安卓視頻硬解。
    發(fā)表于 06-13 15:35

    【作品合集】米爾RK3576開發(fā)板測(cè)評(píng)

    米爾RK3576開發(fā)板測(cè)評(píng)作品合集 產(chǎn)品介紹: RK3576 是瑞芯微一款面向AI市場(chǎng)推出的高性能處理器,它配備了四核Cortex-A72和四 核Cortex-A53 的 CPU,集成了6TOPS
    發(fā)表于 09-11 10:19

    新品體驗(yàn) | RK3576開發(fā)板

    前言:RK3576作為瑞芯微第二代8nm高性能AIOT平臺(tái),一經(jīng)推出便獲得了極大的關(guān)注。廣州眺望電子科技有限公司是一家專注于嵌入式處理器模組研發(fā)與應(yīng)用的國(guó)家高新技術(shù)企業(yè),目前公司已推出的相關(guān)型號(hào)有
    的頭像 發(fā)表于 11-01 08:08 ?3346次閱讀
    新品體驗(yàn) | <b class='flag-5'>RK3576</b>開發(fā)板

    RK3576單板發(fā)布倒計(jì)時(shí):RK3399與RK3576對(duì)比

    好多人說RK3576RK3399的升級(jí)版,某種程度上也可以這么說,RK3576在強(qiáng)大的多媒體功能的基礎(chǔ)上,性能和接口都進(jìn)行了升級(jí) 一、工藝 性能 rk3576采用 Rockchip
    的頭像 發(fā)表于 12-03 16:59 ?2731次閱讀
    <b class='flag-5'>RK3576</b>單板發(fā)布倒計(jì)時(shí):<b class='flag-5'>RK</b>3399與<b class='flag-5'>RK3576</b>對(duì)比

    RK3588與RK3576區(qū)別解析

    以下是RK3576RK3588對(duì)比: 電魚電子SBC-RK3576單板 核心性能:RK3576為四核A72@2.2GHz + 四核A53@1.8GHz + M0協(xié)處理器,算力 58K
    的頭像 發(fā)表于 12-17 14:03 ?4323次閱讀
    <b class='flag-5'>RK</b>3588與<b class='flag-5'>RK3576</b>區(qū)別解析

    想學(xué)人工智能AI?我建議RK3576!

    RK3576擁有強(qiáng)大的計(jì)算性能,輕松應(yīng)對(duì)深度學(xué)習(xí)、圖像處理等高負(fù)載任務(wù)! 高效能低功耗:無論是訓(xùn)練模型還是推理應(yīng)用,都能保持高效穩(wěn)定,續(xù)航更持久! 豐富接口:支持多種外設(shè)連接,滿足你的多樣化開發(fā)需求! 性價(jià)比超高:相比同類產(chǎn)品,RK3
    的頭像 發(fā)表于 02-25 07:44 ?1998次閱讀
    想學(xué)人工智能AI?我建議<b class='flag-5'>RK3576</b>!

    瑞芯微RK3576RK3576S有什么區(qū)別,性能參數(shù)配置與型號(hào)差異解析

    瑞芯微第二代8nm高性能AIOT平臺(tái)RK3576家族再添新成員-RK3576S,先說結(jié)論:相較主型號(hào)的RK3576/RK3576J,性能略有縮減,而功耗有所降低。主要應(yīng)用于商顯終端、智
    的頭像 發(fā)表于 08-14 23:57 ?2638次閱讀
    瑞芯微<b class='flag-5'>RK3576</b>與<b class='flag-5'>RK3576</b>S有什么區(qū)別,性能參數(shù)配置與型號(hào)差異解析

    一文打通Rockchip DP調(diào)試:理到實(shí)戰(zhàn),覆蓋RK3399/RK3576/RK3588全平臺(tái)

    嵌入式開發(fā)中,DisplayPort(DP)接口的調(diào)試常讓工程師頭疼 —— 不同芯片特性差異大、Type-C 與標(biāo)準(zhǔn)口配置不同、高分辨率輸出異常、MST 多屏適配難… 尤其是 Rockchip RK3399、RK3576、RK3
    的頭像 發(fā)表于 02-04 16:14 ?843次閱讀
    一文打通Rockchip DP調(diào)試:<b class='flag-5'>從</b>原<b class='flag-5'>理到</b><b class='flag-5'>實(shí)戰(zhàn)</b>,覆蓋<b class='flag-5'>RK</b>3399/<b class='flag-5'>RK3576</b>/<b class='flag-5'>RK</b>3588全平臺(tái)

    迅為如何在RK3576上部署YOLOv5;基于RK3576構(gòu)建智能門禁系統(tǒng)

    迅為如何在RK3576開發(fā)板上部署YOLOv5;基于RK3576構(gòu)建智能門禁系統(tǒng)
    的頭像 發(fā)表于 11-25 14:06 ?1928次閱讀
    迅為如何在<b class='flag-5'>RK3576</b>上部署YOLOv5;基于<b class='flag-5'>RK3576</b>構(gòu)建智能門禁系統(tǒng)

    硬核進(jìn)階:RK3576 Android15?驅(qū)動(dòng)與系統(tǒng)開發(fā)實(shí)戰(zhàn)指南

    RK3576 探索之旅】系列文章導(dǎo)航及功能全景介紹(基于android14) 之前有出過系列的文章,但這是自己公司定制項(xiàng)目,暫時(shí)沒有相關(guān)硬件,有需求可以私信我,這個(gè)系列主要還是驅(qū)動(dòng)的開發(fā),接下來
    的頭像 發(fā)表于 01-26 22:29 ?783次閱讀
    硬核進(jìn)階:<b class='flag-5'>RK3576</b> Android15?<b class='flag-5'>驅(qū)動(dòng)</b>與系統(tǒng)開發(fā)<b class='flag-5'>實(shí)戰(zhàn)</b>指南
    清河县| 宁远县| 崇左市| 双峰县| 黄山市| 收藏| 桂林市| 牡丹江市| 静海县| 龙山县| 原平市| 平江县| 云林县| 荣成市| 班戈县| 金坛市| 凌云县| 鲜城| 勃利县| 普定县| 明星| 栖霞市| 织金县| 临漳县| 通许县| 曲靖市| 区。| 苏尼特右旗| 饶河县| 公安县| 石棉县| 泽普县| 天气| 舒兰市| 临泉县| 乐平市| 韶关市| 乐山市| 成都市| 小金县| 佛冈县|