(一) pyocd

(1) 什么是pyocd

​ pyocd 是 arm 开发的一个 python 包(python package),该软件包可以使用多种USB调试器对 arm cortex-M 微控制器进行调试、编程(烧录程序)。该软件包还是跨平台的,支持Linux、Mac、Windows。

也就是说,可以通过 pyocd 使用一些调试器来调试、擦除、烧录基于 arm cortex-M(M0/M3/M4/M7/M23/M33) 内核的单片机。目前支持 Daplink、ST-Link、jlink。

目前从 pyocd github 上看到的,pyocd 内部(默认)支持70多个常用的单片机,但是通过使用 CMSIS-Packs 几乎支持所有基于 comtex-m 内核的单片机。

​ 这里不关注 pyocd 调试功能,只关注把 pyocd 用作上位机来操作 MCU 的功能,可以通过两种方式使用 pyocd:

  • pyocd 提供了命令行工具,使用这工具可以用来调试、烧录、擦除 MCU
  • pyocd 提供了python API,可是使用这些API来实现控制 MCU(读取MCU寄存器、暂停、运行、复位MCU等)

(2) 安装

​ pyocd 支持的系统: windows、linux、Mac

由于 pyocd 是基于 python,所以需要先安装 python,pyocd 支持的 python 版本为:Python 3.6.0 or later.

安装方法有:

  • 下载 pyocd 的源码安装

从 GitHub 获取源码:

git clone https://github.com/mbedmicro/pyOCD.git

进入pyOCD目录,使用如下命令安装:

python setup.py install
  • 通过pip安装
pip install -U pyocd

python3 -mpip install --pre -U git+https://github.com/pyocd/pyOCD.git@develop

参考:https://pypi.org/project/pyocd/

(3) Libusb

daplink V1 使用的是 HID 协议,只要安装pyocd是可以用的,如果使用 daplink V2、ST-Link、j-link 的话,需要安装 libusb,pyocd 里面的文档给出了安装方法。

我的做法是把 libusb.dll 复制到 python 安装目录:

(二)如何使用pyocd命令行工具

首先打开命令行,windows 中可以是命令提示符或者 powershell,如下:

如果安装了 git,也可以使用 git bash,如下:

pyocd 的使用方法是在命令行中输入:

pyocd + 子命令 + 参数

在命令行中输入 pyocd 或者 pyocd -h 回车,如下图,就会输出 pyocd 的使用方法及 pyocd 的子命令:

根据上面说明,看下我安装的版本:

从上图中可以看到 0.30.2 版本有 9 个子命令,但其中 commander 跟 cmd、gdbserver 跟 gdb 是相同功能的。所以,总的来说有 9 个功能不同的子命令。分别是:

  • commander跟cmd: 可交互的终端,
  • erase: 擦除命令
  • flash:烧录命令
  • reset:复位设备
  • gdbserver跟gdb:用于gdb调试的
  • json:以json格式输出信息
  • list:可以列出dap-link、目标IC、特定板子的信息
  • pack:用于管理CMSIS-Pack
  • server

如果想知道上述命令的用法可以使用 pyocd + 上述中的一个命令 + -h/--help,如下:

这些命令各有什么用呢?什么情况下要用什么命令?这些命令怎么配合使用?

比如,使用 j-link 给 MCU 下载固件,一般会使用上位机 j-flash 通过 jlink 下载,首先 上位机 j-flash 能找到 j-link,然后需要选择所下载的 MCU,然后选择所要下载的固件,这 3 步都设置好后,就可以下载程序了,

根据这些,依次介绍 pyocd 的命令:

  • list or json:查看能够使用的调试器、支持的 MCU
  • pack:管理支持的 MCU
  • flash & erase : 对 MCU 进行编程、擦除

(1)pyocd list 命令

从 pyocd 帮助信息来看:

list List information about probes, targets, or boards.

可以知道 list 命令使用来查看 调试器、目标芯片、板子的信息,

  • pyocd list / pyocd list -p

列出连接到电脑上的 dap link 或者 ST link,当没接如任何pyocd所支持的设备时,如下:

接入了一个 daplink 跟 jlink 后如下:

(1.1) pyocd list -t/--target

列出所支持的IC,可以是内置的,也可以是通过安装pack获得支持的,

上面图片展示了列出了 pyocd 内置的一部分 MCU。

我的电脑中已近安装了 GD32F350 的pack,上图中,GD32F350 系列后面就显示了 pack

(1.2) pyocd list -b/--board

列出所支持的板子,如下:

(2)pyocd json 命令

json Output information as JSON.

以 json 格式输出信息,输出什么信息呢? 看下 json 命令帮助:

从上图可以看到 pyocd json 一共可以输出4中信息:probes、targets、boards、features。分别看下这4中会输出什么。

(2.1)pyocd list -p

当电脑没有接入任何 pyocd 支持的设备时:

可以看到输出了所安装的 pyocd 版本信息,接了一块ST的开发板后,如下:

可以看到,输出的除了 pyocd 版本信息外,还有所接板子的信息:板子上调试器的ID、板的名字等。

再试一下,接一块没有连接目标 MCU 的 Daplink,输出的信息如下:

(2.2) pyocd json -t

从帮助信息来看,是输出所有已知的 target,先试下pyocd json -t命令,如下:

输出一大堆数据,除了有pyocd 版本信息外,就是一些MCU的信息,有MCU的厂商、型号,还有该信息是内置的还是来自pack。

试下能不能输出指定 MCU 的信息:

从上述结果来看,好像是不行。

pyocd list 跟 pyocd json 功能应该是差不多的,都是输出一些信息,如接入了电脑的调试器信息,系统所支持的单片机等,只不过输出方式不同,pyocd list 是直接输出相关信息,pyocd json 是以 json 格式输出相关信息。

(3)pyocd pack 命令

pyocd 通过两种方法支持 MCU,一个是内置的(builtin),这个数量有限,还有一个是通过 pack 来支持,需要用pyocd 操作什么 MCU,安装对应的 pack , 类似 keil5 ,新安装的 Keil5 不支持任何单片机,如果要使用新安装的keil 支持某类型号单片机,需要安装对应的软件包。

pyocd 提供了一个内置的子命令来对pack进行管理,安装、查找、删除等,来看下 pyocd pack 命令的帮助信息:

送上图来看,有5个功能选项:

  • -c:清楚保存在电脑上的pack信息
  • -u:更新pack索引
  • -s:显示已安装的pack
  • -f:查找某个IC对应的pack
  • -i:安装指定的pack

pyocd 使用的 pack 有个默认的存放路劲,我电脑上为:

C:\Users\Administrator\AppData\Local\cmsis-pack-manager\cmsis-pack-manager

pyocd pack 命令就是对该目录的文件进行管理。

(3.1)pyocd pack -U

使用方法为:

pyocd pack -u
或者
pyocd pack --update

第一次使用该命令的时候,会在pyocd存放pack文件的默认路劲下下载不同厂商不同系列 MCU 的 pack 的描述文件(pdsc文件)和 index.json、aliases.json 文件。执行过一次之后,会从网络上更新相应的文件。下图是一个执行pyocd pack -u的结果,有出现错误。

下图是执行了pyocd pack -u 后,pack 所在文件夹多了很多文件:

(3.2)pyocd pack -f

使用方法为:

pyocd pack -f partnumber

该命令会显示出对应型号 MCU 的 pack 的信息,如下图,显示了 stm32f042 所对应 pack 的信息

(3.3)pyocd pack -i

使用方法为:

pyocd pack -i partnumber

该命令安装指定型号MCU的pack,如下图:

不过,由于网络的问题,一般很难下载完成,跟keil下载pack一样,非常慢,经常下载失败,可以手动下载所需的pack,然后放到对应目录。

(3.4)pyocd pack -s

使用方法为:

pyocd pack -s

列出所安装的pack,如果还未安装任何pack,该命令执行结果为:

安装有pack后,执行结果为:

(4)pyocd flash 命令

测试硬件是 Daplink+STM32F042F4 最小系统,Daplink 我自己用 STM32F042F4做的,如下:

STM32F042F42 的测试程序是用 Cube MX 创建工程,由于板子上没有其他外设,但是 Daplink 有 USB 转 TTL,实现了个 STM32F042 Uart 输出的测试程序,主要程序如下:

  /* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */ /* USER CODE BEGIN 3 */
printf("STM32F042:%d\r\n",i);
i++;
HAL_Delay(1000);
}
/* USER CODE END 3 */

正常跑起来是这样:

第一次测试,首先执行 pyocd list查看是否成功识别到设备,确认能够找到 daplink 后。

pyocd flash -h 输出的帮助信息看不出来 pyocd flash 应该怎么用:

非常多选项,这里只关注烧录的功能,通过查阅 pyocd 的文档,了解到可以使用如下命令来给MCU烧录程序:

pyocd flash -t mcu_partnumber  firmware

我的 MCU 是 stm32f042f4,测试固件是 pyocd_test.hex,尝试使用命令 :

pyocd flash --t stm32f042f4 ./pyocd_test.hex来烧录程序,结果如下:

结果显示不支持 stm32f042f4,使用 list 查看下目前环境下支不支持 042:

下载 stm32f042 的 pack:

可以找到 STM32F042 了,重新试下烧录:

从这结果看是烧录成功了,看了下板子,也成功跑起来了:

(5)pyocd erase 命令

pyocd 帮助信息中对该指令的描述是:

erase Erase entire device flash or specified sectors.

也就是说可以使用该指令对 设备 进行全擦或者指定扇区,pyocd earse帮助信息如下:

我尝试使用了如下命令:

(5.1) 整片擦除:-c/--chip

看了下板子已经没有输出了,

(5.2) 擦除扇区:-s/--sector

该命令需要加一个扇区地址,如果没加的话,会不成功,如下是没加地址的:

对于目标芯片,如果添加的地址不对,也会操作不成功:

添加正确的地址结果如下:

(5)使用 pyocd 操作 STM32F051

试下安装 STM32051 的 pack,看下能不能通过安装 STM32f051 的 pack 来使 pyocd 支持 STM32f051,首先查看已安装的 pack,查询结果如下,

PS D:\project\USB\Daplink\my_dap\doc> pyocd pack -s
Vendor Pack Version
---------------------------

从上述结果来看,尚未安装任何 pack,然后尝试下载 stm32f051 pack:

PS D:\project\USB\Daplink\my_dap\doc> pyocd pack -i STM32F051C8Tx
Downloading packs (press Control-C to cancel):
Keil::STM32F0xx_DFP::2.0.0

等了很久,执行完上述命令后,尝试烧录,结果如下:

PS D:\project> pyocd flash -t stm32f051r8 .\stm32051_test.hex
0001009:CRITICAL:__main__:Failed to open CMSIS-Pack 'C:\Users\dell\AppData\Local\cmsis-pack-manager\cmsis-pack-manager\Keil\STM32F0xx_DFP\2.0.0.pack': File is not a zip file
Traceback (most recent call last):
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyocd-0.23.1.dev12-py3.7.egg\pyocd\target\pack\cmsis_pack.py", line 88, in __init__
self._pack_file = zipfile.ZipFile(file_or_path, 'r')
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\zipfile.py", line 1200, in __init__
self._RealGetContents()
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\zipfile.py", line 1267, in _RealGetContents
raise BadZipFile("File is not a zip file")
zipfile.BadZipFile: File is not a zip file The above exception was the direct cause of the following exception: Traceback (most recent call last):
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyocd-0.23.1.dev12-py3.7.egg\pyocd\__main__.py", line 343, in run
self._COMMANDS[self._args.cmd](self)
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyocd-0.23.1.dev12-py3.7.egg\pyocd\__main__.py", line 470, in do_flash
options=convert_session_options(self._args.options))
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyocd-0.23.1.dev12-py3.7.egg\pyocd\core\helpers.py", line 241, in session_with_chosen_probe
return Session(probe, auto_open=auto_open, options=options, **kwargs)
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyocd-0.23.1.dev12-py3.7.egg\pyocd\core\session.py", line 175, in __init__
or Board(self, self.options.get('target_override'))
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyocd-0.23.1.dev12-py3.7.egg\pyocd\board\board.py", line 48, in __init__
pack_target.ManagedPacks.populate_target(target)
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyocd-0.23.1.dev12-py3.7.egg\pyocd\target\pack\pack_target.py", line 84, in populate_target
targets = ManagedPacks.get_installed_targets()
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyocd-0.23.1.dev12-py3.7.egg\pyocd\target\pack\pack_target.py", line 71, in get_installed_targets
pack = CmsisPack(pack_path)
File "C:\Users\dell\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyocd-0.23.1.dev12-py3.7.egg\pyocd\target\pack\cmsis_pack.py", line 91, in __init__
file_or_path, err)), err)
File "<string>", line 3, in raise_from
pyocd.target.pack.cmsis_pack.MalformedCmsisPackError: Failed to open CMSIS-Pack 'C:\Users\dell\AppData\Local\cmsis-pack-manager\cmsis-pack-manager\Keil\STM32F0xx_DFP\2.0.0.pack': File is not a zip file

还是不能成功下载,从上述信息来看应该是解析stm32f0的pack失败,到目录C:\Users\dell\AppData\Local\cmsis-pack-manager\cmsis-pack-manager\Keil\STM32F0xx_DFP\看了下,有文件2.0.0.pack,20多兆。

手动从https://www.keil.com/dd2/Pack/#/eula-container下载了Keil.STM32F0xx_DFP.2.0.0.pack,有60多兆,对比下,问题是使用pyocd pack -i安装的stm32f051的pack有问题。把自己下载的Keil.STM32F0xx_DFP.2.0.0.pack重命名为2.0.0.pack,放到目录C:\Users\dell\AppData\Local\cmsis-pack-manager\cmsis-pack-manager\Keil\STM32F0xx_DFP\,然后重新烧录:

PS D:\project\USB\Daplink\my_dap\doc> pyocd flash -t stm32f051r8 .\stm32051_test.hex
[====================] 100%
0001733:INFO:loader:Erased 3072 bytes (3 sectors), programmed 3072 bytes (3 pages), skipped 0 bytes (0 pages) at 7.12 kB/s

板子运行起来了,下载成功。

还做了实验,还是使用STM32F051板子,跑一个很简单的程序,控制一个LED闪烁,试了下指定芯片跟不指定芯片有什么区别,效果怎样,如下:

从上面结果来看,如果没指定芯片,虽然说从结果来看,是执行了擦除操作,可是板子还在运行,LED还在闪烁,指定了芯片后,执行完任务后,LED不再闪烁了。

(三)使用 pyocd python api

这里尝试下使用pyocd python api来操作单片机。

环境是:

  • PC: windows10

  • python

  • 硬件

    调试器:一块跑Daplink V1的STM32F042最小系统

    目标板:一个STM32F042最小系统

    如下:

首先导入库:

from pyocd.probe.aggregator import DebugProbeAggregator
from pyocd.board.board import Board
from pyocd.core.helpers import ConnectHelper
from pyocd.core.target import Target
import logging
from pyocd.core.memory_map import MemoryType
from pyocd.core.coresight_target import CoreSightTarget
from pyocd.coresight.cortex_m import CortexM

按照 pyocd 的文档,首先是创建一个 Session ,如下:

session = ConnectHelper.session_with_chosen_probe(None, None)
session.open()

然后可以获取到当前 session 中的 board,如下:

board = session.board
print("Board MSG:")
print("Board's name:%s" % board.name)
print("Board's description:%s" % board.description)
print("Board's target_type:%s" % board.target_type)
print("Board's unique_id:%s" % board.unique_id)
print("Board's test_binary:%s" % board.test_binary)
print("Unique ID: %s" % board.unique_id)

上述程序执行结果如下:

从上述信息来看,是可以成功是别到我的调试器,但是没有正确显示目标芯片,除了我要输出的信息外,还有一段内容,说的是当前目标类芯片类型型是 cortex_m,选这类型可以进行调试但不能烧录,可以通过 --target 或者 target_override 选项来指定目标芯片。

修改代码如下,通过 target_override 指定了我的目标芯片:

session = ConnectHelper.session_with_chosen_probe(target_override="stm32f042f4")
session.open()
board = session.board
print("Board MSG:")
print("Board's name:%s" % board.name)
print("Board's description:%s" % board.description)
print("Board's target_type:%s" % board.target_type)
print("Board's unique_id:%s" % board.unique_id)
print("Board's test_binary:%s" % board.test_binary)
print("Unique ID: %s" % board.unique_id)

运行结果为:

这回显示了我的目标芯片。

成功了获取到了调试器的信息,现在来试下获取当前环境下目标芯片的信息,代码如下:

target = board.target
print("Part number:%s" % target.part_number)
memory_map = target.get_memory_map()
ram_region = memory_map.get_default_region_of_type(MemoryType.RAM)
rom_region = memory_map.get_boot_memory()
print("menory map:")
print(memory_map)
print("ram_region:")
print(ram_region)
print("rom_region:")
print(rom_region)

运行结果为:

从上述结果来看,是可以成功获取到目标芯片的 part number、Flash 跟 RAM 信息。

通过查看 pyocd 的源码,target 实例有个 irq_table 属性,看下这个属性会输出什么信息:

print("Irq:")
print(target.irq_table)

输出如下:

试下读取单片机一些寄存器:

print("pc reg: 0x%X" % target.read_core_register('pc'))
print("CPUID:0x%x" % target.read32(CortexM.CPUID))
print("device id:0x%x" % target.read32(0x40015800))
print("flash size:%x KB" % target.read32(0x1FFFF7CC))

运行结果如下:

  • 第一个读取 PC 寄存器的值

    这个读出来的值究竟对不对,没去查看,不过从这个值的大小来看(在0x8000000到‭8004000之前‬),应该是对的。

  • 第二个,读取CPUID的值

    RM0091 Reference manual (stm32f0x2 参考手册) 中关于CPU ID 部分如下:

stm32f042是arm M0 ,根据上述内容,该芯片的CPU ID为:

​ ARM V0 ARMv6-M M0 Revision

​ 0x41 0 c c20 0

也就是0x140cc200,跟读取到的结果对的上,

  • 第三个读取设备ID

    RM0091 Reference manual (stm32f0x2 参考手册) 中也有 设备 ID 的内容,如下:

从文档来看,读取出来的值也是对的,

  • 第四个,读取Flash大小

目标 IC 是 STM32F042F4,Flash 实际大小是 16K,读出来的也是 16K

完整代码为:

from pyocd.probe.aggregator import DebugProbeAggregator
from pyocd.board.board import Board
from pyocd.core.helpers import ConnectHelper
from pyocd.core.target import Target
import logging
from pyocd.core.memory_map import MemoryType
from pyocd.core.coresight_target import CoreSightTarget
from pyocd.coresight.cortex_m import CortexM
session = ConnectHelper.session_with_chosen_probe(target_override="stm32f042f4")
session.open()
board = session.board
print("Board MSG:")
print("Board's name:%s" % board.name)
print("Board's description:%s" % board.description)
print("Board's target_type:%s" % board.target_type)
print("Board's unique_id:%s" % board.unique_id)
print("Board's test_binary:%s" % board.test_binary)
print("Unique ID: %s" % board.unique_id)
target = board.target
print("Part number:%s" % target.part_number)
memory_map = target.get_memory_map()
ram_region = memory_map.get_default_region_of_type(MemoryType.RAM)
rom_region = memory_map.get_boot_memory()
print("menory map:")
print(memory_map)
print("ram_region:")
print(ram_region)
print("rom_region:")
print(rom_region) print("Irq:")
print(target.irq_table) print("pc reg: 0x%X" % target.read_core_register('pc'))
print("CPUID:0x%x" % target.read32(CortexM.CPUID))
print("device id:0x%x" % target.read32(0x40015800))
print("flash size:%d KB" % (target.read32(0x1FFFF7CC) & 0x0000ffff))

对于这段代码,我试着在创建 session 的时候,把指定目标芯片的型号跟实际使用的芯片型号设置成不一样,

第一次看到跑的结果的时候,有点懵逼,不过想了下,合理。

参考:

api_examples:pyOCD\docs\api_examples.md,即pyocd源码目录下docs/api_examples.md

architecture:pyOCD\pyOCD-0.25.0\docs\architecture.md

(四)可以用 pyocd 用来做什么

还是只关注 pyocd 烧录的功能,在这个点上面,可以怎么使用 pyocd 呢?

对于 pyocd 命令,当然是直接用来烧录了,pyocd 是跨平台的,不管使用的是 ST-Link、J-link、Daplink,由于一般情况下使用的都是固定的几种 MCU,把 pyocd 命令 做成脚本文件,如 windows 的 bat、Linux Shell 脚本,很方面使用。

对于使用 pyocd python api,可以使用 python 做个烧录的上位机,对于使用 ST-Link 烧录 ST MCU、J-link 有个j-flash 来说好像是多次一举,不过对于一些使用场景,如对于不是做单片机开发的,如硬件工程师、做上位机开发的纯软件工程师、或者其他不懂这方面的人来说,使用 j-flash 设置选项比较多可能一时用不起来,如果使用 pyocd python api 做个上位机一键烧录,就可以解决这问题。

还有对于使用 daplink 的人来说,把 daplink 用于调试是非常方便的,不用担心什么时候被识别为盗版的导致用不了而耽误工作,由于 daplink 没有对应的上位机,要使用 daplink 烧录的话就不方便了,pyocd python api 做个上位机就可以解决这问题,如下是我用 pyocd + PyQT 做的一个上位机给一个软件工程师用,只能烧录 STM32F103C8,直接把软件给过去就可以用起来,不用教这软件的使用方法,这还可以做的跟简单,一键烧录。

还有一些场景,如,如果机器给到了客户,要更新固件的话,直接把固件给客户,怕客户拿到了固件,另外找个便宜点的供应商做个硬件,不再跟你买了,岂不亏大了,如果自己做个烧录上位机,对给过去的固件做些加密什么的,客户就无法用其他烧录软件烧录这固件了,还可以加个数量限制,就不怕客户直接用这个来生成烧录了,或者直接把固件放到一个服务器里,只给个烧录上位机就可以烧录,原理上这也是可以实现的。

玩转 pyocd的更多相关文章

  1. 玩转spring boot——快速开始

    开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv web应用程序 打开Eclipse,新建Maven项目 选择quic ...

  2. [C#] 软硬结合第二篇——酷我音乐盒的逆天玩法

    1.灵感来源: LZ是纯宅男,一天从早上8:00起一直要呆在电脑旁到晚上12:00左右吧~平时也没人来闲聊几句,刷空间暑假也没啥动态,听音乐吧...~有些确实不好听,于是就不得不打断手头的工作去点击下 ...

  3. [C#] 了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数

    了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数 目录 简介 特点 方法的参数 方法的返回值 与批处理交互的一个示例 简介 我们知道,新建一个控制台应用程序的时候,IDE 会同时创建 ...

  4. 玩转spring boot——开篇

    很久没写博客了,而这一转眼就是7年.这段时间并不是我没学习东西,而是园友们的技术提高的非常快,这反而让我不知道该写些什么.我做程序已经有十几年之久了,可以说是彻彻底底的“程序老炮”,至于技术怎么样?我 ...

  5. 玩转spring boot——结合redis

    一.准备工作 下载redis的windows版zip包:https://github.com/MSOpenTech/redis/releases 运行redis-server.exe程序 出现黑色窗口 ...

  6. 玩转spring boot——AOP与表单验证

    AOP在大多数的情况下的应用场景是:日志和验证.至于AOP的理论知识我就不做赘述.而AOP的通知类型有好几种,今天的例子我只选一个有代表意义的“环绕通知”来演示. 一.AOP入门 修改“pom.xml ...

  7. 玩转spring boot——结合JPA入门

    参考官方例子:https://spring.io/guides/gs/accessing-data-jpa/ 接着上篇内容 一.小试牛刀 创建maven项目后,修改pom.xml文件 <proj ...

  8. 玩转spring boot——结合JPA事务

    接着上篇 一.准备工作 修改pom.xml文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

  9. 玩转spring boot——结合AngularJs和JDBC

    参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ...

随机推荐

  1. 创建者模式 -- 单例模式(反射&序列化)

    看的视频:https://www.bilibili.com/video/av43896218/?p=286 实现方式:(构造器私有,提供一个外部可以访问的方法(可以提供实例)) 1.饿汉式:线程安全, ...

  2. 数据库表的自增ID createDate和updateDate 用JPA注解代替触发器实现

    对于数据库表的自增ID , createDate和updateDate 等字段,用JPA注解代替触发器实现,效率会高很多. 由于这些属性很多entity都有 可以写成两个基本entity :BaseE ...

  3. Centos7 yum安装 MySQL5.7.25

    扩展:在CentOS中默认安装有MariaDB,这个是MySQL的分支,但为了需要,还是要在系统中安装MySQL,而且安装完成之后可以直接覆盖掉MariaDB. 1 下载并安装MySQL官方的 Yum ...

  4. Java刷题常用API

    目录 输入输出 快速查看 最大最小值 string stringbuilder 集合 map queue stack set 优先队列 PriorityQueue (Heap) 数组 静态数组 动态数 ...

  5. HTTP 2.0标准针对HTTP 1.X的五点改进

    HTTP 2.0兼容HTTP 1.X,同时大大提升了Web性能,进一步减少了网络延迟,减少了前端方面的工作.HTTP 1.X存在的缺点如下: 1)HTTP 1.0一次只允许在一个TCP连接上发起一个请 ...

  6. 攻防世界-crypto-Decrypt-the-Message(Poem Codes-诗歌密码)

    题目来源:su-ctf-quals-2014题目描述:解密这段信息! 下载附件,内容如下 The life that I have Is all that I have And the life th ...

  7. sql-5-事务,索引

    事务 1.ACID概念 原子性(Atomicity) 要么都成功,要么都失败 一致性(consistency) 事务前后的数据完整性保持一致 持久性(Durability) 事务一旦提交则不可逆,持久 ...

  8. 基于 Blazor 打造一款实时字幕

    早先在录制视频的时候一直使用的是 obs-auto-subtitle 作为实时字幕展示功能.不过这个是以 OBS 插件的形式存在,不管是语言和功能上都有一定的限制.故而使用 Blazor server ...

  9. 记一次错误:mid=front+(rear-front)>>1;

    设rear=6,front=4,mid=front+(rear-front)>>1; mid应该等于5的,但结果却是3. 错误原因:"+"运算符的优先级高于" ...

  10. 02_Java基础类型和包装类型

    基本数据类型 包装类名称 所占字节数 默认值 byte Byte 1 0 short Short 2 0 Int Integer 4 0 long Long 8 0L double Double 8 ...