ARM PMU

PMU单元概览

ARM PMU概要
PMU作为一个扩展功能,是一种非侵入式的调试组件。
对PMU寄存器的访问可以通过CP15协处理器指令和Memory-Mapped地址。

基于PMUv2架构,A7处理器在运行时可以收集关于处理器和内存的各种统计信息。对于处理器来说这些统计信息中的事件非常有用,你可以利用它们来调试或者剖析代码。

更详细内容参考:
《Arm CoreSight Performance Monitoring Unit Architecture》:关于PMU架构介绍,包括寄存器解释、规格、安全等等。
《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》:介绍了PMU在Armv7-A/R中的实现。
《Chapter C12 The Performance Monitors Extension》:PMU基本功能介绍
《Appendix D2 Recommended Memory-mapped and External Debug Interfaces for the Performance Monitors》:PMU寄存器介绍。

在这里插入图片描述

PMU 配置流程

PMU有两个主流版本PMUv2和PMUv3,其中大部分32位ARM的处理器使用的PMUv2,大部分64位ARM的处理器使用的PMUv3。两者的主要区别是读取相关寄存器的汇编命令不一样,PMUv2 寄存器是通过CP15 协处理器和外部APB接口来编程,PMUv3则是可以直接使用寄存器的名字来通过mrs和msr命令来读取。

设置和使用事件计数器
本节概述了在Cortex-A15(Armv7-A)上设置和使用事件计数器所需的步骤。Armv8-A处理器的步骤相似,尽管可能会有一些细微的变化。

您可以选择不激活周期计数器(标记为可选的步骤)。这不会影响事件计数器,因为它们独立于周期计数器。如果不需要读出周期数,则可以关闭计数器,这将减少PMU对系统的性能影响。

(不是必需的)启用PMU用户态访问(即允许在EL0操作PMU相关寄存器),如果你要测的代码是在用户态,那么你必须要把性能监视器用户启用寄存器(PMUSERENR)中的EN,bit [0]设置为1。如果仅在内核态使用(即EL1)则不必设置PMUSERENR寄存器。
启用PMU–在性能监视器控制寄存器(PMCR)中,将E,bit [0]设置为1。 配置事件计数器
在性能监视器事件计数器选择寄存器(PMSELR)中,将计数器编号(0-5)写入您要配置的SEL位[4:0],即选用那个计数器。
在性能监视器事件类型选择寄存器(PMXEVTYPER)中,将事件编号(从event事件列表中,见上表)写入evtCount,bits [7:0],以便选择计数器正在监视的事件。
启用已配置的事件计数器 -在性能监视器计数启用设置寄存器 (PMCNTENSET)中,将Px,bit[x](其中x对应于要启用的计数器0-5)设置为1。
(可选)启用周期计数器(CCNT) -在性能监视器计数启用设置寄存器(PMCNTENSET)中,将C,bit [31]设置为1。
(可选)重置周期计数器(CCNT) -在性能监视器控制寄存器(PMCR)中,将C,bit [2]设置为1。
重置事件计数器 -在性能监视器控制寄存器(PMCR)中,将P,bit [1]设置为1。
现在配置了计数器,并将在执行继续时监视感兴趣的事件。

(可选)禁用周期计数器(CCNT)-在性能监视器计数启用清除寄存器(PMCNTENCLR)中,将C,bit [31]设置为1。
禁用事件计数器 -在性能监视器计数启用清除寄存器(PMCNTENCLR)中,将Px,bit
[x](其中x对应于要禁用的计数器0-5)设置为1。 读取事件计数器的值
在性能监视器事件计数器选择寄存器(PMSELR)中,将计数器号(0-5)写入到您要读取的SEL位[4:0]。
所选计数器的值存储在性能监视器所选事件计数寄存器(PMXEVCNTR)中。
(可选)读取周期计数器(CCNT)的值-周期计数器的值存储在性能监视器周期计数寄存器(PMCCNTR)中。

PMU驱动的实现 纯汇编版本

pmu_v7.S

/*------------------------------------------------------------
Performance Monitor Block
------------------------------------------------------------*/.arm @ Make sure we are in ARM mode..text.align 2.global getPMN @ export this function for the linker/* Returns the number of progammable counters uint32_t getPMN(void) */getPMN:MRC p15, 0, r0, c9, c12, 0 /* Read PMNC Register */MOV r0, r0, LSR #11 /* Shift N field down to bit 0 */AND r0, r0, #0x1F /* Mask to leave just the 5 N bits */BX lr.global pmn_config @ export this function for the linker/* Sets the event for a programmable counter to record *//* void pmn_config(unsigned counter, uint32_t event) *//* counter = r0 = Which counter to program (e.g. 0 for PMN0, 1 for PMN1) *//* event = r1 = The event code */
pmn_config:AND r0, r0, #0x1F /* Mask to leave only bits 4:0 */MCR p15, 0, r0, c9, c12, 5 /* Write PMNXSEL Register */MCR p15, 0, r1, c9, c13, 1 /* Write EVTSELx Register */BX lr.global ccnt_divider @ export this function for the linker/* Enables/disables the divider (1/64) on CCNT *//* void ccnt_divider(int divider) *//* divider = r0 = If 0 disable divider, else enable dvider */
ccnt_divider:MRC p15, 0, r1, c9, c12, 0 /* Read PMNC */CMP r0, #0x0 /* IF (r0 == 0) */BICEQ r1, r1, #0x08 /* THEN: Clear the D bit (disables the divisor) */ORRNE r1, r1, #0x08 /* ELSE: Set the D bit (enables the divisor) */MCR p15, 0, r1, c9, c12, 0 /* Write PMNC */BX lr/* --------------------------------------------------------------- *//* Enable/Disable *//* --------------------------------------------------------------- */.global enable_pmu @ export this function for the linker/* Global PMU enable *//* void enable_pmu(void) */
enable_pmu:MRC p15, 0, r0, c9, c12, 0 /* Read PMNC */ORR r0, r0, #0x01 /* Set E bit */MCR p15, 0, r0, c9, c12, 0 /* Write PMNC */BX lr.global disable_pmu @ export this function for the linker/* Global PMU disable *//* void disable_pmu(void) */
disable_pmu:MRC p15, 0, r0, c9, c12, 0 /* Read PMNC */BIC r0, r0, #0x01 /* Clear E bit */MCR p15, 0, r0, c9, c12, 0 /* Write PMNC */BX lr.global enable_ccnt @ export this function for the linker/* Enable the CCNT *//* void enable_ccnt(void) */
enable_ccnt:MOV r0, #0x80000000 /* Set C bit */MCR p15, 0, r0, c9, c12, 1 /* Write CNTENS Register */BX lr.global disable_ccnt @ export this function for the linker/* Disable the CCNT *//* void disable_ccnt(void) */
disable_ccnt:MOV r0, #0x80000000 /* Clear C bit */MCR p15, 0, r0, c9, c12, 2 /* Write CNTENC Register */BX lr.global enable_pmn @ export this function for the linker/* Enable PMN{n} *//* void enable_pmn(uint32_t counter) *//* counter = r0 = The counter to enable (e.g. 0 for PMN0, 1 for PMN1) */
enable_pmn:MOV r1, #0x1 /* Use arg (r0) to set which counter to disable */MOV r1, r1, LSL r0MCR p15, 0, r1, c9, c12, 1 /* Write CNTENS Register */BX lr.global disable_pmn @ export this function for the linker/* Enable PMN{n} *//* void disable_pmn(uint32_t counter) *//* counter = r0 = The counter to enable (e.g. 0 for PMN0, 1 for PMN1) */
disable_pmn:MOV r1, #0x1 /* Use arg (r0) to set which counter to disable */MOV r1, r1, LSL r0MCR p15, 0, r1, c9, c12, 1 /* Write CNTENS Register */BX lr.global enable_pmu_user_access @ export this function for the linker/* Enables User mode access to the PMU (must be called in a priviledged mode) *//* void enable_pmu_user_access(void) */
enable_pmu_user_access:MRC p15, 0, r0, c9, c14, 0 /* Read PMUSERENR Register */ORR r0, r0, #0x01 /* Set EN bit (bit 0) */MCR p15, 0, r0, c9, c14, 0 /* Write PMUSERENR Register */BX lr.global disable_pmu_user_access @ export this function for the linker/* Disables User mode access to the PMU (must be called in a priviledged mode) *//* void disable_pmu_user_access(void) */
disable_pmu_user_access:MRC p15, 0, r0, c9, c14, 0 /* Read PMUSERENR Register */BIC r0, r0, #0x01 /* Clear EN bit (bit 0) */MCR p15, 0, r0, c9, c14, 0 /* Write PMUSERENR Register */BX lr/* --------------------------------------------------------------- *//* Counter read registers *//* --------------------------------------------------------------- */.global read_ccnt @ export this function for the linker/* Returns the value of CCNT *//* uint32_t read_ccnt(void) */
read_ccnt:MRC p15, 0, r0, c9, c13, 0 /* Read CCNT Register */BX lr.global read_pmn @ export this function for the linker/* Returns the value of PMN{n} *//* uint32_t read_pmn(uint32_t counter) *//* counter = r0 = The counter to read (e.g. 0 for PMN0, 1 for PMN1) */
read_pmn:AND r0, r0, #0x1F /* Mask to leave only bits 4:0 */MCR p15, 0, r0, c9, c12, 5 /* Write PMNXSEL Register */MRC p15, 0, r0, c9, c13, 2 /* Read current PMNx Register */BX lr/* --------------------------------------------------------------- *//* Software Increment *//* --------------------------------------------------------------- */.global pmu_software_increment @ export this function for the linker/* Writes to software increment register *//* void pmu_software_increment(uint32_t counter) *//* counter = r0 = The counter to increment (e.g. 0 for PMN0, 1 for PMN1) */
pmu_software_increment:MOV r1, #0x01MOV r1, r1, LSL r0MCR p15, 0, r1, c9, c12, 4 /* Write SWINCR Register */BX lr/* --------------------------------------------------------------- *//* Overflow & Interrupt Generation *//* --------------------------------------------------------------- */.global read_flags @ export this function for the linker/* Returns the value of the overflow flags *//* uint32_t read_flags(void) */
read_flags:MRC p15, 0, r0, c9, c12, 3 /* Read FLAG Register */BX lr.global write_flags @ export this function for the linker/* Writes the overflow flags *//* void write_flags(uint32_t flags) */
write_flags:MCR p15, 0, r0, c9, c12, 3 /* Write FLAG Register */BX lr.global enable_ccnt_irq @ export this function for the linker/* Enables interrupt generation on overflow of the CCNT *//* void enable_ccnt_irq(void) */
enable_ccnt_irq:MOV r0, #0x80000000MCR p15, 0, r0, c9, c14, 1 /* Write INTENS Register */BX lr.global disable_ccnt_irq @ export this function for the linker/* Disables interrupt generation on overflow of the CCNT *//* void disable_ccnt_irq(void) */
disable_ccnt_irq:MOV r0, #0x80000000MCR p15, 0, r0, c9, c14, 2 /* Write INTENC Register */BX lr.global enable_pmn_irq @ export this function for the linker/* Enables interrupt generation on overflow of PMN{x} *//* void enable_pmn_irq(uint32_t counter) *//* counter = r0 = The counter to enable the interrupt for (e.g. 0 for PMN0, 1 for PMN1) */
enable_pmn_irq:MOV r1, #0x1 /* Use arg (r0) to set which counter to disable */MOV r0, r1, LSL r0MCR p15, 0, r0, c9, c14, 1 /* Write INTENS Register */BX lr.global disable_pmn_irq @ export this function for the linker/* Disables interrupt generation on overflow of PMN{x} *//* void disable_pmn_irq(uint32_t counter) *//* counter = r0 = The counter to disable the interrupt for (e.g. 0 for PMN0, 1 for PMN1) */
disable_pmn_irq:MOV r1, #0x1 /* Use arg (r0) to set which counter to disable */MOV r0, r1, LSL r0MCR p15, 0, r0, c9, c14, 2 /* Write INTENC Register */BX lr/* --------------------------------------------------------------- *//* Reset Functions *//* --------------------------------------------------------------- */.global reset_pmn @ export this function for the linker/* Resets the programmable counters *//* void reset_pmn(void) */
reset_pmn:MRC p15, 0, r0, c9, c12, 0 /* Read PMNC */ORR r0, r0, #0x02 /* Set P bit (Event Counter Reset) */MCR p15, 0, r0, c9, c12, 0 /* Write PMNC */BX lr.global reset_ccnt @ export this function for the linker/* Resets the CCNT *//* void reset_ccnt(void) */
reset_ccnt:MRC p15, 0, r0, c9, c12, 0 /* Read PMNC */ORR r0, r0, #0x04 /* Set C bit (Event Counter Reset) */MCR p15, 0, r0, c9, c12, 0 /* Write PMNC */BX lr.end @end of code, this line is optional.
/* ------------------------------------------------------------ */
/* End of v7_pmu.s */
/* ------------------------------------------------------------ */

pmu_v7.h

// ------------------------------------------------------------
// PMU for Cortex-A/R (v7-A/R)
// ------------------------------------------------------------#ifndef _V7_PMU_H
#define _V7_PMU_H// Returns the number of progammable counters
unsigned int getPMN(void);// Sets the event for a programmable counter to record
// counter = r0 = Which counter to program (e.g. 0 for PMN0, 1 for PMN1)
// event = r1 = The event code (from appropiate TRM or ARM Architecture Reference Manual)
void pmn_config(unsigned int counter, unsigned int event);// Enables/disables the divider (1/64) on CCNT
// divider = r0 = If 0 disable divider, else enable dvider
void ccnt_divider(int divider);//
// Enables and disables
//// Global PMU enable
// On ARM11 this enables the PMU, and the counters start immediately
// On Cortex this enables the PMU, there are individual enables for the counters
void enable_pmu(void);// Global PMU disable
// On Cortex, this overrides the enable state of the individual counters
void disable_pmu(void);// Enable the CCNT
void enable_ccnt(void);// Disable the CCNT
void disable_ccnt(void);// Enable PMN{n}
// counter = The counter to enable (e.g. 0 for PMN0, 1 for PMN1)
void enable_pmn(unsigned int counter);// Enable PMN{n}
// counter = The counter to enable (e.g. 0 for PMN0, 1 for PMN1)
void disable_pmn(unsigned int counter);//
// Read counter values
//// Returns the value of CCNT
unsigned int read_ccnt(void);// Returns the value of PMN{n}
// counter = The counter to read (e.g. 0 for PMN0, 1 for PMN1)
unsigned int read_pmn(unsigned int counter);//
// Overflow and interrupts
//// Returns the value of the overflow flags
unsigned int read_flags(void);// Writes the overflow flags
void write_flags(unsigned int flags);// Enables interrupt generation on overflow of the CCNT
void enable_ccnt_irq(void);// Disables interrupt generation on overflow of the CCNT
void disable_ccnt_irq(void);// Enables interrupt generation on overflow of PMN{x}
// counter = The counter to enable the interrupt for (e.g. 0 for PMN0, 1 for PMN1)
void enable_pmn_irq(unsigned int counter);// Disables interrupt generation on overflow of PMN{x}
// counter = r0 = The counter to disable the interrupt for (e.g. 0 for PMN0, 1 for PMN1)
void disable_pmn_irq(unsigned int counter);//
// Counter reset functions
//// Resets the programmable counters
void reset_pmn(void);// Resets the CCNT
void reset_ccnt(void);//
// Software Increment// Writes to software increment register
// counter = The counter to increment (e.g. 0 for PMN0, 1 for PMN1)
void pmu_software_increment(unsigned int counter);//
// User mode access
//// Enables User mode access to the PMU (must be called in a priviledged mode)
void enable_pmu_user_access(void);// Disables User mode access to the PMU (must be called in a priviledged mode)
void disable_pmu_user_access(void);#endif
// ------------------------------------------------------------
// End of v7_pmu.h
// ------------------------------------------------------------

使用demo

#include "v7_pmu.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>int random_range(int max);
void pmu_start(unsigned int event0,unsigned int event1,unsigned int event2,unsigned int event3,unsigned int event4,unsigned int event5);
void pmu_stop(void);int main ( int argc, char *argv[] ){
int matrix_size;
int i,j,k,z;// To access CPU time
clock_t start, end;
double cpu_time_used;if ( argc != 2 ) {fputs ( "usage: $prog n", stderr );exit ( EXIT_FAILURE );}matrix_size = (int)strtol(argv[1],NULL,10);printf("square matrix size = %dn", matrix_size);/*Using time function output for seed value*/unsigned int seed = (unsigned int)time(NULL);srand(seed);/* Initialize square matrix with command line input value */
int a[matrix_size][matrix_size], b[matrix_size][matrix_size], c[matrix_size][matrix_size];/* Intialize both A[][] and B[][] with random values between 0-5 and set C[][] to zero*/for(i=0;i<matrix_size;i++){for(j=0;j<matrix_size;j++){a[i][j]=random_range(6);b[i][j]=random_range(6);c[i][j]=0;}}/* Multiply A[][] and B[][] and store into C[][]*/start = clock();for(z=0;z<7;z++){if(z==0)pmu_start(0x01,0x02,0x03,0x04,0x05,0x06);if(z==1)pmu_start(0x07,0x08,0x09,0x0A,0x0B,0x0C);if(z==2)pmu_start(0x0D,0x0E,0x0F,0x10,0x11,0x12);if(z==3)pmu_start(0x50,0x51,0x60,0x61,0x62,0x63);if(z==4)pmu_start(0x64,0x65,0x66,0x67,0x68,0x6E);if(z==5)pmu_start(0x70,0x71,0x72,0x73,0x74,0x81);if(z==6)pmu_start(0x82,0x83,0x84,0x85,0x86,0x8A);for(i=0; i<matrix_size; i++){for(j=0; j<matrix_size; j++){for(k=0; k<matrix_size; k++){/* c[0][0]=a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]; */c[i][j] += a[i][k]*b[k][j];}}}pmu_stop();}end = clock();cpu_time_used = (end - start) / ((double) CLOCKS_PER_SEC);printf("CPU time used = %.4lfn",cpu_time_used);
printf("square matrix size = %dn", matrix_size);return 0;
}int random_range(int max){return ((rand()%(max-1)) +1);
}void pmu_start(unsigned int event0,unsigned int event1,unsigned int event2,unsigned int event3,unsigned int event4,unsigned int event5){enable_pmu(); // Enable the PMUreset_ccnt(); // Reset the CCNT (cycle counter)reset_pmn(); // Reset the configurable counterspmn_config(0, event0); // Configure counter 0 to count event code 0x03pmn_config(1, event1); // Configure counter 1 to count event code 0x03pmn_config(2, event2); // Configure counter 2 to count event code 0x03pmn_config(3, event3); // Configure counter 3 to count event code 0x03pmn_config(4, event4); // Configure counter 4 to count event code 0x03pmn_config(5, event5); // Configure counter 5 to count event code 0x03enable_ccnt(); // Enable CCNTenable_pmn(0); // Enable counterenable_pmn(1); // Enable counterenable_pmn(2); // Enable counterenable_pmn(3); // Enable counterenable_pmn(4); // Enable counterenable_pmn(5); // Enable counterprintf("CountEvent0=0x%x,CountEvent1=0x%x,CountEvent2=0x%x,CountEvent3=0x%x,CountEvent4=0x%x,CountEvent5=0x%xn", event0,event1,event2,event3,event4,event5);
}void pmu_stop(void){unsigned int cycle_count, overflow, counter0, counter1, counter2, counter3, counter4, counter5;disable_ccnt(); // Stop CCNTdisable_pmn(0); // Stop counter 0disable_pmn(1); // Stop counter 1disable_pmn(2); // Stop counter 2disable_pmn(3); // Stop counter 3disable_pmn(4); // Stop counter 4disable_pmn(5); // Stop counter 5counter0 = read_pmn(0); // Read counter 0counter1 = read_pmn(1); // Read counter 1counter2 = read_pmn(2); // Read counter 2counter3 = read_pmn(3); // Read counter 3counter4 = read_pmn(4); // Read counter 4counter5 = read_pmn(5); // Read counter 5cycle_count = read_ccnt(); // Read CCNToverflow=read_flags(); //Check for overflow flagprintf("Counter0=%d,Counter1=%d,Counter2=%d,Counter3=%d,Counter4=%d,Counter5=%dn", counter0, counter1,counter2,counter3,counter4,counter5);printf("Overflow flag: = %d, Cycle Count: = %d nn", overflow,cycle_count);
}

ARMv8 支持的事件列表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ARMv7 支持的事件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考文档

https://blog.csdn.net/qq1798831241/article/details/108188200: ARM PMU详解及使用
https://blog.csdn.net/chichi123137/article/details/80145914: ARM CPU 之 PMU部件(性能监控单元)
arm文档:Using the PMU and the Event Counters in DS-5
https://zhuanlan.zhihu.com/p/276680818: perf_event框架之:ARM PMU硬件
https://github.com/afrojer/armperf/blob/master/v7_pmu.S :PMU PERF
http://t.csdnimg.cn/g5a8k

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/143085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI:83-基于深度学习的手势识别与实时控制

🚀 本文选自专栏:人工智能领域200例教程专栏 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的代码,详细讲解供大家学习,希望可以帮到大家。欢迎订阅支持,正在不断更新中,…

【Linux奇遇记】我和Linux的初次相遇

&#x1f308;个人主页: Aileen_0v0 &#x1f525;系列专栏:Linux奇遇记系列专栏&#x1f4ab;"没有罗马,那就自己创造罗马~" 目录 前端和后端的介绍 1.前端 2.后端 3.前后端区别 Linux在前后端开发中的角色 如何学习Linux 去进行程序开发 Linux的常见根目…

爆款元服务!教你如何设计高使用率卡片

元服务的概念相信大家已经在 HDC 2023 上有了很详细的了解&#xff0c;更轻便的开发方式&#xff0c;让开发者跃跃欲试。目前也已经有很多开发者开发出了一些爆款元服务&#xff0c;那么如何让你的元服务拥有更高的传播范围、更高的用户使用率和更多的用户触点呢&#xff1f;设…

MySQL 索引事务

MySQL 索引&事务 文章目录 MySQL 索引&事务1. 索引1.1 概念1.2 作用1.3 使用场景1.4 使用 2. 事务2.1 为什么使用事务2.2 事务概念2.3 事务的特性2.4 使用 1. 索引 1.1 概念 索引(index)是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的…

学好Python-新手小白如何做?

新手小白如何学好Python?有哪些参考方法吗?这是一个老生常谈的话题了。今天为大家带来两位前辈的分享&#xff0c;他们给出了非常实用的方法和思路&#xff0c;希望对你有所帮助。 1、多练&#xff0c;两个字&#xff1a;多练 如果真的要说方法可以参考如下&#xff1a; ①…

排查线程阻塞问题

案例代码 package first;import java.util.concurrent.TimeUnit;public class DeadLock {private static volatile Object lock new Object();public static void main(String[] args) {new Thread(() -> {test1();}).start();new Thread(() -> {test2();}).start();}p…

centos下安装mysql8版本

1、如果服务器没有wget&#xff0c;先下载wget工具 sudo yum install wget 2、下载指定mysql版本的tar包 sudo wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.21-1.el7.x86_64.rpm-bundle.tar 3、解压tar包 sudo tar -xvf mysql-8.0.21-1.el7.x86_64.rpm…

《QT从基础到进阶·二十四》按钮组QButtonGroup,单选框QRadioButton和多选框QCheckBox

1、按钮组QButtonGroup 如果有多个单选按钮&#xff0c;可以统一放进一个按钮组。 图中有三个单选按钮放进了一个QGroupBox,并且设置了水平布局&#xff0c;现在要将这三个单选按钮放进一个按钮组&#xff0c;之前的想法是先把三个按钮加入按钮组&#xff0c;再把按钮组放进QG…

MATLAB中uiresume函数用法

目录 语法 说明 示例 按下按钮后恢复执行 使用函数调用恢复执行 uiresume函数的功能是恢复暂停程序的执行。 语法 uiresume uiresume(f) 说明 uiresume 恢复与当前图窗 (gcf) 关联的对应 uiwait 调用暂停的程序执行。 uiresume(f) 恢复与图窗 f 关联的对应 uiwait 调用…

开发企业微信群机器人,实现定时提醒

大家好&#xff0c;我是鱼皮&#xff0c;今天分享一个用程序解决生活工作问题的真实案例。 说来惭愧&#xff0c;事情是这样的&#xff0c;在我们公司&#xff0c;每天都要轮流安排一名员工&#xff08;当然也包括我&#xff09;去楼层中间一个很牛的饮水机那里接水。但由于大…

【杂谈】体验AI帮助编写代码,有提升效率,AI本身提升空间也很大

体验AI帮助编写代码 ​专栏内容&#xff1a; 手写数据库toadb 本专栏主要介绍如何从零开发&#xff0c;开发的步骤&#xff0c;以及开发过程中的涉及的原理&#xff0c;遇到的问题等&#xff0c;让大家能跟上并且可以一起开发&#xff0c;让每个需要的人成为参与者。 本专栏会定…

租用服务器带宽类型应用

服务器带宽类型多样&#xff0c;以满足不同行业的需求。本文将介绍香港常见的服务器带宽类型及其应用领域。 1. 共享带宽 共享带宽是指多个用户共同使用同一台服务器的带宽资源。这种带宽类型适用于小型企业或个人网站&#xff0c;因为其成本较低。由于多个用户共享带宽资源&…

Java的XWPFTemplate word生成列表

Java的XWPFTemplate工具类导出word.docx的使用_xwpftemplate 语法_youmdt的博客-CSDN博客 如果是表格的列表参考上面这篇文章即可&#xff0c;比较复杂的列表遍历暂时还没找到方法&#xff0c;只能手动创建表格了 上面是模板&#xff0c;非常简单&#xff0c;以为我们是要自己创…

HTTP 常见的请求头

面试官&#xff1a;说说 HTTP 常见的请求头有哪些? 作用&#xff1f; 一、是什么 HTTP头字段&#xff08;HTTP header fields&#xff09;,是指在超文本传输协议&#xff08;HTTP&#xff09;的请求和响应消息中的消息头部分 它们定义了一个超文本传输协议事务中的操作参数 …

阿里云服务器搭建sql 服务

阿里云搭建mysql服务 环境准备 系统镜像 ubuntu 如果买点的实例不是ubuntu 系统镜像&#xff0c;需要停止服务之后&#xff0c;更改镜像 更新 apt-get &#xff1a; 更新apt-get: sudo apt-get update 如果没有出现&#xff1a;apt-get 找不到此命令的错误&#xff0c;可能是…

LLM App ≈ 数据ETL管线

虽然现有的 LLM 应用程序工具&#xff08;例如 LangChain 和 LlamaIndex&#xff09;对于构建 LLM 应用程序非常有用&#xff0c;但在初始实验之外不建议使用它们的数据加载功能。 当我构建和测试我的LLM应用程序管道时&#xff0c;我能够感受到一些尚未开发和破解的方面的痛苦…

css3 初步了解

1、css3的含义及简介 简而言之&#xff0c;css3 就是 css的最新标准&#xff0c;使用css3都要遵循这个标准&#xff0c;CSS3 已完全向后兼容&#xff0c;所以你就不必改变现有的设计&#xff0c; 2、一些比较重要的css3 模块 选择器 1、标签选择器&#xff0c;也称为元素选择…

龙迅LT9211D MIPI(DSI/CSI)转LVDS和集创北方ICN6202 MIPIDSI转LVDS比对

龙迅LT9211D描述&#xff1a; Lontium LT9211D是一款高性能的MIPI DSI/CSI- 2到双端口LVDS转换器。LT9211D反序列化输入的MIPI视频数据&#xff0c;解码数据包&#xff0c;并将格式化的视频数据流转换为AP和移动显示面板或摄像机之间的LVDS发射机输出。LT9211D支持最大14 dB输…

谷歌提出AGI的6大原则,和5大能力等级

随着ChatGPT等大模型的出现,AGI概念正在从哲学层面快速转向实际应用落地&#xff0c;并且ChatGPT已经展示出了初级AGI的功能&#xff08;如AutoGPT&#xff09;,有不少专家认为&#xff0c;AGI时代可能在10年内到来。 因此&#xff0c;需要一个明确的技术框架来讨论和衡量不同…

IP-guard flexpaper远程命令执行漏洞复现 [附POC]

文章目录 IP-guard flexpaper RCE漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 IP-guard flexpaper RCE漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测…