keil下载程序具体过程3:从jlink的log开始

news2025/1/16 8:55:56

引言

        本篇文章开始,跟着jlink的log,我们将跟踪镜像文件具体的下载过程。

一、jlink的log

        下面的是keil点击Download按钮输出的log。

FromELF: creating hex file...
".\Objects\Project.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:16
Load "MDK-ARM\\Objects\\Project.axf"
Set JLink Project File to "MDK-ARM\JLinkSettings.ini"
* JLink Info: Device "CORTEX-M4" selected.
JLink info:
------------
DLL: V7.22b, compiled Jun 17 2021 17:22:49
Firmware: J-Link ARM-OB STM32 compiled Aug 22 2012 19:52:04
Hardware: V7.00
S/N : 20090937
Feature(s) : RDI,FlashDL,FlashBP,JFlash,GDBFull
* JLink Info: Found SW-DP with ID 0x2BA01477
* JLink Info: DPv0 detected
* JLink Info: Scanning AP map to find all available APs
* JLink Info: AP[1]: Stopped AP scan as end of AP map has been reached
* JLink Info: AP[0]: AHB-AP (IDR: 0x24770011)
* JLink Info: Iterating through AP map to find AHB-AP to use
* JLink Info: AP[0]: Core found
* JLink Info: AP[0]: AHB-AP ROM base: 0xE00FF000
* JLink Info: CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
* JLink Info: Found Cortex-M4 r0p1, Little endian.
* JLink Info: FPUnit: 6 code (BP) slots and 2 literal slots
* JLink Info: CoreSight components:
* JLink Info: ROMTbl[0] @ E00FF000
* JLink Info: ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7
* JLink Info: ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 003BB002 DWT
* JLink Info: ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 002BB003 FPB
* JLink Info: ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 003BB001 ITM
* JLink Info: ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU
ROMTableAddr = 0xE00FF000
* JLink Info: Reset: Halt core after reset via DEMCR.VC_CORERESET.
* JLink Info: Reset: Reset device via AIRCR.SYSRESETREQ.
Target info:
------------
Device: ARMCM4_FP
VTarget = 3.300V
State of Pins:
TCK: 0, TDI: 0, TDO: 1, TMS: 0, TRES: 1, TRST: 1
Hardware-Breakpoints: 6
Software-Breakpoints: 8192
Watchpoints: 4
JTAG speed: 4000 kHz
Erase Done.
Programming Done.

        这是keil下面的调试窗口显示的log。根据上面的分析,可以看到,JLink第一件事是去加载Project.axf文件,这个是keil生成的工程文件。在keil编译了源代码之后,会生成对应的Project.axf、Project.hex、Project.bin文件。bin文件只有镜像文件,纯二进制,hex文件在bin文件的基础上添加了地址信息,axf在hex文件的基础上再添加了调试信息部分。

出现的这两行log值得注意:
JLink Info: AP[0]: Core found
JLink Info: AP[0]: AHB-AP ROM base: 0xE00FF000

0xE00FF000是什么地址?在《Cortex-M3权威指南》里面搜索下可以看到如下地址排列(截取一部分):

 可以看到,ROM表的地址位于0xE00F_F000–––0xE00F_FFFF这个范围,"AP[0]: AHB-AP ROM
base: 0xE00FF000"说AHB-AP的ROM基地址在0xE00FF000,这里可以引出之前文章的ROM表。

JLink Info: ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7
JLink Info: ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 003BB002 DWT
JLink Info: ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 002BB003 FPB
JLink Info: ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 003BB001 ITM
JLink Info: ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU

        这5行log就是ROM表的内容,从上往下分别是:SCS-M7、DWT、FPB、ITM、TPIU
从上面的表中可以看到,DWT、FPB、ITM、TPIU都在里面,这几个单元具体什么意思,请参考博主之前的文章:Cortext-M3系列:调试组件(9)_紫川宁520的博客-CSDN博客

        可以看到这5个单元的地址也不是默认的。各家芯片厂商可以根据自己的需求自定义端口的地址。(扯得有点远了)

        后面紧接着是将JLink的配置信息写入到JLinkSettings.ini中。可以看到ini文件中的信息(我也不太懂里面具体啥意思,以后搞明白了再更新这个部分)。

 

        在”JLink info:“部分,我们可以在开头看到JLink相关的信息。随后的 "JLink Info: Found SW-DP with ID 0x2BA01477"和上面的信息,跟我们在keil的配置中设置的一样。SWD为0x2BA01477,SN为20090937。

在keil的工程下面还有一个jlink的log,这个才是真正的jlink日志文件,下面放其中的一部分。

T47A4 000:231.035 JLINK_SetWarnOutHandler(...)

T47A4 000:231.057 JLINK_OpenEx(...)

T47A4 000:237.253 Feature(s): RDI,FlashDL,FlashBP,JFlash,GDBFull

T47A4 000:239.217 TELNET listener socket opened on port 19021

T47A4 000:239.360 WEBSRV Starting webserver

T47A4 000:239.463 WEBSRV Webserver running on local port 19080 T47A4 000:239.487 JLINK_SetErrorOutHandler(...)

T47A4 000:239.513 JLINK_ExecCommand("ProjectFile = "MDK-ARM\JLinkSettings.ini"", ... ).

T47A4 000:248.435 Ref file found at: C:\Keil_v5\ARM\Segger\JLinkDevices.ref

T47A4 000:248.537 XML referenced by ref file: C:\Program Files (x86)\SEGGER\JLink\JLinkDevices.xml

T47A4 000:249.085 C:\Program Files (x86)\SEGGER\JLink\JLinkDevices.xml evaluated successfully.

T47A4 000:267.144 JLINK_ExecCommand("Device = ARMCM4_FP", ...).

T47A4 000:267.466 JLINK_GetHardwareVersion()

......

T47A4 000:267.544 JLINK_GetOEMString(...)

T47A4 000:267.549 JLINK_TIF_Select(JLINKARM_TIF_SWD)

T47A4 000:269.794 JLINK_SetResetType(JLINKARM_RESET_TYPE_NORMAL)

T47A4 000:271.663 Found SW-DP with ID 0x2BA01477

T47A4 000:280.994 Old FW that does not support reading DPIDR via DAP jobs

T47A4 000:289.582 DPv0 detected

T47A4 000:289.615 Scanning AP map to find all available APs

T47A4 000:295.659 AP[1]: Stopped AP scan as end of AP map has been reached

T47A4 000:295.699 AP[0]: AHB-AP (IDR: 0x24770011)

T47A4 000:295.705 Iterating through AP map to find AHB-AP to use

T47A4 000:305.475 AP[0]: Core found

T47A4 000:305.499 AP[0]: AHB-AP ROM base: 0xE00FF000

T47A4 000:310.516 CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)

T47A4 000:310.536 Found Cortex-M4 r0p1, Little endian.

T47A4 000:412.248 -- Max. mem block: 0x00002C18

T47A4 000:412.697 CPU_ReadMem(4 bytes @ 0xE000EDF0)

T47A4 000:413.283 CPU_WriteMem(4 bytes @ 0xE000EDF0)

T47A4 000:414.297 CPU_ReadMem(4 bytes @ 0xE0002000)

T47A4 000:415.240 FPUnit: 6 code (BP) slots and 2 literal slots

T47A4 000:415.247 CPU_ReadMem(4 bytes @ 0xE000EDFC)

T47A4 000:416.032 CPU_WriteMem(4 bytes @ 0xE000EDFC)

T47A4 000:416.778 CPU_ReadMem(4 bytes @ 0xE0001000)

T47A4 000:417.627 CPU_WriteMem(4 bytes @ 0xE0001000)

T47A4 000:418.364 CPU_ReadMem(4 bytes @ 0xE000ED88)

T47A4 000:419.092 CPU_WriteMem(4 bytes @ 0xE000ED88)

T47A4 000:420.015 CPU_ReadMem(4 bytes @ 0xE000ED88)

T47A4 000:421.009 CPU_WriteMem(4 bytes @ 0xE000ED88)

T47A4 000:421.923 CoreSight components:

T47A4 000:421.997 ROMTbl[0] @ E00FF000

T47A4 000:422.003 CPU_ReadMem(64 bytes @ 0xE00FF000)

T47A4 000:423.384 CPU_ReadMem(32 bytes @ 0xE000EFE0)

T47A4 000:424.420 ROMTbl0: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7 T47A4 000:424.425 CPU_ReadMem(32 bytes @ 0xE0001FE0)

T47A4 000:425.456 ROMTbl0: E0001000, CID: B105E00D, PID: 003BB002 DWT

T47A4 000:425.471 CPU_ReadMem(32 bytes @ 0xE0002FE0)

T47A4 000:426.420 ROMTbl0: E0002000, CID: B105E00D, PID: 002BB003 FPB

T47A4 000:426.428 CPU_ReadMem(32 bytes @ 0xE0000FE0)

T47A4 000:427.597 ROMTbl0: E0000000, CID: B105E00D, PID: 003BB001 ITM

T47A4 000:427.662 CPU_ReadMem(32 bytes @ 0xE0040FE0)

T47A4 000:428.759 ROMTbl0: E0040000, CID: B105900D, PID: 000BB9A1 TPIU

T47A4 000:428.868 CPU is running

T47A4 000:428.875 CPU_WriteMem(4 bytes @ 0xE000EDF0)

T47A4 000:429.654 CPU is running

T47A4 000:429.709 CPU_WriteMem(4 bytes @ 0xE000EDFC)

T47A4 000:430.525 Reset: Halt core after reset via DEMCR.VC_CORERESET.

T47A4 000:431.541 Reset: Reset device via AIRCR.SYSRESETREQ.

T47A4 000:431.560 CPU is running

T47A4 000:431.571 CPU_WriteMem(4 bytes @ 0xE000ED0C)

T47A4 000:486.058 CPU_ReadMem(4 bytes @ 0xE000EDF0)

T47A4 000:486.763 CPU_ReadMem(4 bytes @ 0xE000EDF0)

T47A4 000:487.567 CPU is running

T47A4 000:487.577 CPU_WriteMem(4 bytes @ 0xE000EDF0)

T47A4 000:488.278 CPU is running

T47A4 000:488.290 CPU_WriteMem(4 bytes @ 0xE000EDFC)

T47A4 000:495.055 CPU_ReadMem(4 bytes @ 0xE000EDF0)

T47A4 000:499.878 CPU_WriteMem(4 bytes @ 0xE0002000)

T47A4 000:500.818 CPU_ReadMem(4 bytes @ 0xE000EDFC)

T47A4 000:501.757 CPU_ReadMem(4 bytes @ 0xE0001000)

T47A4 000:502.559 - 232.763ms

T47A4 000:502.573 JLINK_GetId()

T47A4 000:503.581 - 1.010ms returns 0x2BA01477 T47A4 000:508.670 JLINK_GetFirmwareString(...) T47A4 000:508.688 - 0.019ms T47A4 058:935.486 JLINK_SWO_Control(JLINKARM_SWO_CMD_GET_SPEED_INFO, ...)

.....

JLINK_SWO_Control(JLINKARM_SWO_CMD_GET_SPEED_INFO, ...)

T47A4 080:629.020 - 0.498ms returns 0x00 T47A4 083:195.488 JLINK_Close()

T47A4 083:196.154 CPU_ReadMem(4 bytes @ 0xE0001000)

T47A4 083:197.087 CPU_WriteMem(4 bytes @ 0xE0001000)

T47A4 083:197.834 CPU_WriteMem(4 bytes @ 0xE0001004)

T47A4 000:239.217 :可以看到JLink支持网络调试的。
T47A4 000:239.513:就是刚才将JLink信息写入到ini的那个文件。
T47A4 000:248.435:打开JLinkDevices.ref就是如下所示。

 C:\Keil_v5\ARM\Segger\JLinkDevices.ref是keil安装的JLink相关的部分,”C:\Program Files
(x86)\SEGGER\JLink\“是电脑上安装的JLink驱动的位置。这部分的内容就是配置好jlink的驱动,使用其下载镜像文件。

T47A4 000:248.537:是一个xml文件,打开之后会看到很多芯片的设置,我这里取一个stm32的芯片为例。

 打开之后是一堆设备标签。看名字就行了,很好理解,我们看看Loader指向的文件。打开文件夹,

 里面有一个Readme.txt文件,内容:

         各个elf文件其实根据Reame.txt的内容看,是QSPI FLASH的下载算法。JLink有一个JFlashSPI.exe的工具,猜测应该使用这个算法给SPI Flash下载程序的,elf文件是jlink的下载算法。

T47A4 000:267.466:从这里开始的一些之类就是获取各种信息了。
T47A4 000:271.663:获取了SW-DP的ID,这里已经能和芯片的SW-DP接口通信了。
T47A4 000:289.615:扫描各个AP接口。
T47A4 000:295.699:找到AHB-AP接口,这个就是用于和AHB总线通信的AP接口。
T47A4 000:305.499:这里显示AHB-AP ROM 的地址是0xE00FF000。这个地址前文说过,是ROM表的起始地址,用于检测调试系统有哪些哪些组件。
T47A4 000:412.697 :从这里开始,连续读写地址。0xE000EDF0搜索《M3权威指南》之后,是调试停机控制及状态寄存器。0xE0002000是FPB的基址。0xE000EDFC是调试监视器的地址,调试监视器用于断点,数据观察点,或者是外部调试请求。0xE0001000是DWT的基址。0xE000ED88未找到相关信息。
T47A4 000:422.003:从0xE00FF000地址读取了64个Byte的数据,刚好是ROMTbl的大小(4×4×4Byte = 64B)

我们分析下这个数据,取TPIU为例。将前文的图放到这里,方面查看。

TPIU相关的信息是:

T47A4 000:427.662 CPU_ReadMem(32 bytes @ 0xE0040FE0)
T47A4 000:428.759 ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU

         从0xE0040FE0地址读取32B,读取到的内容第一个字(4B)就是E0040000,这个就是TPIU的地址。TPIU中文名是跟踪端口接口单元,用于将ITM, DWT和ETM的跟踪数据汇聚到TPIU处。TPIU用于把这些跟踪数据格式化并输出到片外,以供跟踪端口分析仪之类的设备接收使用。跟前文所述:ROM表记录调试相关组件信息相一致。

T47A4 000:428.875:0xE000EDF0地址在T47A4 000:412.697 已经说过了。
T47A4 000:431.571:0xE000ED0C是复位控制,是应用程序中断及复位控制寄存器的地址。之后的0xE0002000、0xE000EDFC、0xE0001000在前面都已经论述了。
T47A4 000:502.573:从这里开始就是SWD相关的了,获取SWD速度信息。
 

下面放的是跟下载镜像有关系日志,与上面的日志并不是同一次的,二者无关,博主写文章的时候,多次下载,有些没保存,这里特地说明下。

 T5324 000:386.354 JLINK_WriteMem(0xE0001000, 0x1C Bytes, ...)
T5324 000:386.358 Data: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...
T5324 000:386.372 CPU_WriteMem(28 bytes @ 0xE0001000)
T5324 000:390.509 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T5324 000:390.517 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T5324 000:390.720 CPU_WriteMem(1648 bytes @ 0x20000000)
T5324 000:527.583 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T5324 000:527.598 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T5324 000:527.622 CPU_WriteMem(1648 bytes @ 0x20000000)
T5324 000:563.095 JLINK_WriteMem(0x20000670, 0x200 Bytes, ...)
T5324 000:563.106 Data: 88 08 00 20 D5 01 00 10 8B 0A 00 10 65 0A 00 10 ...
T5324 000:563.126 CPU_WriteMem(512 bytes @ 0x20000670)
.....
T5324 000:695.612 JLINK_WriteMem(0x20000670, 0x200 Bytes, ...)
T5324 000:695.618 Data: 72 74 20 0A 00 00 00 00 4F F0 40 70 E1 EE 10 0A ...
T5324 000:695.628 CPU_WriteMem(512 bytes @ 0x20000670)
T1A34 000:768.192 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T1A34 000:768.209 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T1A34 000:768.232 CPU_WriteMem(1648 bytes @ 0x20000000)

T1A34 000:884.512 JLINK_WriteMem(0x20000000, 0x2 Bytes, ...)
T1A34 000:884.533 Data: FE E7
T1A34 000:884.552 CPU_WriteMem(2 bytes @ 0x20000000)

T5324 000:563.095:开始写入bin文件,按照512Byte写入(下面的图是使用二进制查看bin文件的)

可以看到,T5324 000:563.106 Data: 88 08 00 20 D5 01 00 10 8B 0A 00 10 65 0A 00 10 ...
Data数据刚好对应bin文件的开始16Byte。

T5324 000:695.612:写入bin文件的最后一个块(以512B为单位,不足512B的补0)

 查看MCU芯片手册的时候,发现上面对flash记载的是:以扇区为单位组织,每扇区512B,这里对上了。

T5324 000:695.618 Data: 72 74 20 0A 00 00 00 00 4F F0 40 70 E1 EE 10 0A ...中,对应最后一个扇区(C00行),很明显是不够512B的,进行补0操作。在keil中已经设置了擦除扇区,写不写0其实都不是很大的问题(猜测)。

 T5324 000:386.354 JLINK_WriteMem(0xE0001000, 0x1C Bytes, ...)
T5324 000:386.358 Data: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...
T5324 000:386.372 CPU_WriteMem(28 bytes @ 0xE0001000)
T5324 000:390.509 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T5324 000:390.517 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T5324 000:390.720 CPU_WriteMem(1648 bytes @ 0x20000000)

第一次写入28B,第二次写入1648B。这部分的日志是什么意思?第一次写入内容告诉芯片要开始写入程序了(猜测),第二次写入的就是flash算法文件,如下图。

至于flash下载文件是个什么东西,放到后面的文章介绍。

了解完JLink下载的过程之后,还有问题:JLink是如何知道该往哪里写入bin文件已经如何写入?
往哪里写很容易知道,在keil里面设置的有。

如何写入的过程我们放到下一篇文章中介绍。

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

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

相关文章

C++ 语言的输入与输出

C 标准 I/O 库包含 iostream、fstream 和 sstringstream。iostream、fstream 比较常用,一般操作于输入和输出,相较于前两者来说 sstringstream 的出现频率就低了许多,一般操作于数据的格式化。为了能更好的理解 C 语言的标准 I/O 库&#xff…

通过MATLAB自动产生Hamming编译码的verilog实现,包含testbench

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 1. 原理 1.1 编码规则 1.2 错误检测和纠正 2. 实现过程 2.1 编码过程 2.2 解码过程 3. 应用领域 3.1 数字通信 3.2 存储系统 3.3 ECC内存 3.4 数据传输 5.算法完整程序工程 1.算法…

MySQL多表关联查询

目录 1. inner join: 2. left join: 3. right join: 4.自连接 5.交叉连接: 6、联合查询 7、子查询 1. inner join: 代表选择的是两个表的交差部分。 内连接就是表间的主键与外键相连,只取得键值一致…

全国各地区数字经济工具变量-文本词频统计(2002-2023年)

数据简介:本数据使用全国各省工作报告,对其中数字经济相关的词汇进行词频统计,从而构建数字经济相关的工具变量。凭借数字经济政策供给与数字经济发展水平的相关系数的显著性作为二者匹配程度的划分依据,一定程度上规避了数字经济…

Vue.js2+Cesium1.103.0 九、淹没分析效果

Vue.js2Cesium1.103.0 九、淹没分析效果 Demo <template><divid"cesium-container"style"width: 100%; height: 100%;"><spanid"button"style"position: absolute; right: 50px; top: 50px; z-index: 999; font-size: 24px…

旅卦-火山旅

前言&#xff1a;人生就像一趟旅行&#xff0c;为谋生奔波也是旅&#xff0c;旅是人生的常态&#xff0c;我们看一下易经里的旅卦&#xff0c;分析下卦辞和爻辞以及自己的理解。 目录 卦辞 爻辞 总结 卦辞 旅&#xff1a;小亨&#xff0c;旅贞吉。 卦序&#xff1a;穷大者…

oracle 增加控制文件

oracle 增加控制文件 1、看control_file路径 SQL> show parameter controlNAME TYPE VALUE ------------------------------------ ----------- ------------------------------ control_file_record_keep_time integer …

Grafana展示k8s中pod的jvm监控面板/actuator/prometheus

场景 为保障java服务正常运行&#xff0c;对服务的jvm进行监控&#xff0c;通过使用actuator组件监控jvm情况&#xff0c;使用prometheus对数据进行采集&#xff0c;并在Grafana展现。 基于k8s场景 prometheus数据收集 配置service的lable&#xff0c;便于prometheus使用labl…

大数据课程I2——Kafka的架构

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 掌握Kafka的架构&#xff1b; ⚪ 掌握Kafka的Topic与Partition&#xff1b; 一、Kafka核心概念及操作 1. producer生产者&#xff0c;可以是一个测试线程&#xff0c;也…

青大数据结构【2014】

一、单选 二、简答 为了解决顺序队列的假溢出问题,提出了循环队列,即把存储队列的表从逻辑上看成一个环 判别队列空和满有三种方法: 1)采用计数器判别,空时,计数器为0;满时,计数器为maxsize; 2)另设一个布尔变量以匹配队列的满和空; 3)少用一个元素的空间,约…

无向图邻接矩阵(C++ 代码)

#include<iostream>//无向图邻接矩阵 #define mvnum 100 using namespace std; typedef char Vertextype;//顶点数据类型 typedef int Arctype;//边权值类型 typedef struct {Vertextype vexs[mvnum];//顶点表Arctype arcs[mvnum][mvnum];//邻接矩阵int vexnum, arcnum;/…

解决macOS执行fastboot找不到设备的问题

背景 最近准备给我的备用机Redmi Note 11 5G刷个类原生的三方ROM&#xff0c;MIUI实在是用腻了。搜罗了一番&#xff0c;在XDA上找到了一个基于Pixel Experience开发的ROM&#xff1a;PixelExperience Plus for Redmi Note 11T/11S 5G/11 5G/POCO M4 Pro 5G (everpal)&#xf…

JavaScript激活严格模式

在JavaScript中&#xff0c;严格模式是一种特殊的模式&#xff0c;通过’use strict’;去激活严格模式&#xff01;在 JavaScript 中&#xff0c;“use strict” 是一种指令&#xff0c;表示在代码运行时启用严格模式&#xff0c;从而禁止使用一些不安全或者不规范的语法&#…

MFC第三十天 通过CToolBar类开发文字工具栏和工具箱、GDI+边框填充以及基本图形的绘制方法、图形绘制过程的反色线模型和实色模型

文章目录 CControlBar通过CToolBar类开发文字工具栏和工具箱CMainFrame.hCAppCMainFrm.cppCMainView.hCMainView.cppCEllipse.hCEllipse.cppCLine.hCLine.cppCRRect .hCRRect .cpp CControlBar class AFX_NOVTABLE CControlBar : public CWnd{DECLARE_DYNAMIC(CControlBar)pro…

【高频面试题】JVM篇

文章目录 一、JVM组成1.什么是程序计数器2.什么是Java堆&#xff1f;3.能不能介绍一下方法区(元空间&#xff09;4.你听过直接内存吗5.什么是虚拟机栈6.垃圾回收是否涉及栈内存&#xff1f;7.栈内存分配越大越好吗&#xff1f;8.方法内的局部变量是否线程安全&#xff1f;9.什么…

ntfy 实现消息订阅和通知(无需注册、无需服务器,太好了)

目录 一、下载 ntfy 的Delphi 库&#xff08;打开ntfy for Delphi 的开源库地址&#xff09; 二、创建发布消息程序 三、订阅&#xff08;接收&#xff09;消息程序 四、说明&#xff1a; 五、程序下载&#xff08;包含库&#xff09;&#xff1a; ntfy 可让你在任何电脑上通…

【muduo】关于自动增长的缓冲区

目录 为什么需要缓冲区自动增长的缓冲区buffer数据结构buffer类 写详细比较费时间&#xff0c;就简单总结下。 总结自Linux 多线程服务端编程&#xff1a;使用 muduo C 网络库 Muduo网络编程&#xff1a; IO-multiplexnon-blocking 为什么需要缓冲区 Non-blocking IO 的核心…

1990-2021年上市公司绿色专利和绿色使用新型申请获得分类号数据

1990-2021年上市公司绿色专利申请获得分类号数据 1、时间&#xff1a;1990-2021年 2、来源&#xff1a;国家知识产权局 3、指标&#xff1a; 绿色专利申请数量&#xff08;分A类 B类C类D类E类F类G类H类&#xff09;、绿色专利获得数量&#xff08;分A类 B类C类D类E类F类G类…

商业智能BI,如何区别联机事务处理(OLTP)和联机分析处理(OLAP)

商业智能(Business Intelligence&#xff0c;简称&#xff1a;BI)&#xff0c;又称商业智慧或商务智能&#xff0c;指用现代数据仓库技术、线上分析处理技术、数据挖掘和数据展现技术进行数据分析以实现商业价值。 商业智能BI - 派可数据数据可视化分析平台 定义为下列软件工具…

容器虚拟化基础之NameSpace

“只想从这无边的寂寞中逃出来。” 一、什么是虚拟化、容器化&#xff1f; 物理机:实际的服务器或者计算机。 这是相对于虚拟机而言的对实体计算机的称呼&#xff0c;物理机提供虚拟机以硬件环境&#xff0c;有时候也称为"宿主"或"寄主"。 虚拟机: 指通过软…