yocto machine class解析之st-partitions-image

news2024/11/30 14:44:48

yocto machine class解析之st-partitions-image

stm32mp157 yocto的meta-st-stm32mp layer中提供了几个class,后续几篇文章重点分析这些class文件:
在这里插入图片描述第一篇就从st-partitions-image.bbclass 开始,st所有创建image的bb文件都会引用st-partitions-image,包括bootfs userfs vendorfs等image的bb 文件。这个class会在image编译以后生成分区镜像。


ENABLE_PARTITIONS_IMAGE ?= "1"

PARTITIONS_CONFIG ??= ""
PARTITIONS_IMAGE ??= ""
PARTITIONS_MOUNTPOINT ??= ""

python __anonymous () {
    # We check first if it is requested to generate any partition images
    if d.getVar('ENABLE_PARTITIONS_IMAGE') != "1":
        bb.note('ENABLE_PARTITIONS_IMAGE not enabled')
        return

    # -----------------------------------------------------------------------------
    # Update the partition configuration set by user
    # -----------------------------------------------------------------------------
    partitionsconfigflags = d.getVarFlags('PARTITIONS_CONFIG')
    # The "doc" varflag is special, we don't want to see it here
    partitionsconfigflags.pop('doc', None)
    partitionsconfig = (d.getVar('PARTITIONS_CONFIG') or "").split()
    # Init image_summary_list
    image_summary_list = ''
    if len(partitionsconfig) > 0:
        for config in partitionsconfig:
            for f, v in partitionsconfigflags.items():
                if config == f:
                    items = v.split(',')
                    if items[0]:
                        if len(items) > 5:
                            raise bb.parse.SkipRecipe('Only image,label,mountpoint,size,type can be specified!')
                        # Make sure that we're dealing with partition image and not rootfs image
                        if len(items) > 2 and items[2]:
                            # Mount point available, so we're dealing with partition image
                            # PARTITIONS_IMAGE appending
                            bb.debug(1, "Appending '%s' to PARTITIONS_IMAGE." % items[0])
                            d.appendVar('PARTITIONS_IMAGE', ' ' + items[0])
                            # PARTITIONS_MOUNTPOINT appending
                            bb.debug(1, "Appending '%s' to PARTITIONS_MOUNTPOINT." % items[2])
                            d.appendVar('PARTITIONS_MOUNTPOINT', ' ' + items[2])

                        # Update IMAGE vars for each partition image
                        if items[1]:
                            bb.debug(1, "Set UBI_VOLNAME to %s for %s partition image." % (items[1], items[0]))
                            d.setVar('UBI_VOLNAME_pn-%s' % d.expand(items[0]), items[1])
                            if d.expand(items[1])[-2:] != 'fs':
                                bb.debug(1, "Set IMAGE_NAME_SUFFIX to '.%sfs' for %s partition image." % (items[1], items[0]))
                                d.setVar('IMAGE_NAME_SUFFIX_pn-%s' % d.expand(items[0]), '.' + items[1] + 'fs')
                            else:
                                bb.debug(1, "Set IMAGE_NAME_SUFFIX to '.%s' for %s partition image." % (items[1], items[0]))
                                d.setVar('IMAGE_NAME_SUFFIX_pn-%s' % d.expand(items[0]), '.' + items[1])
                        else:
                            bb.fatal('[PARTITIONS_CONFIG] Missing label setting for %s image' % items[0])
                        if items[2]:
                            bb.debug(1, "Set IMAGE_PARTITION_MOUNTPOINT to %s for %s partition image." % (items[2], items[0]))
                            d.setVar('IMAGE_PARTITION_MOUNTPOINT_pn-%s' % d.expand(items[0]), items[2])
                        if items[3]:
                            bb.debug(1, "Set IMAGE_ROOTFS_SIZE to %s for %s partition image." % (items[3], items[0]))
                            d.setVar('IMAGE_ROOTFS_SIZE_pn-%s' % d.expand(items[0]), items[3])
                        else:
                            bb.fatal('[PARTITIONS_CONFIG] Missing size setting for %s image' % items[0])

                        # Manage IMAGE_SUMMARY_LIST configuration according to PARTITION_CONFIG set
                        if d.getVar('ENABLE_IMAGE_LICENSE_SUMMARY') == "1":
                            if not items[2]:
                                # Set '/' as default mountpoint for rootfs in IMAGE_SUMMARY_LIST
                                items[2] = '/'
                            image_summary_list += items[0] + ':' + items[2] + ';'

                        # Manage multiubi volume list STM32MP_UBI_VOLUME
                        if bb.utils.contains('IMAGE_FSTYPES', 'stmultiubi', True, False, d) and d.getVar('ENABLE_MULTIVOLUME_UBI') == "1":
                            bb.debug(1, "Appending '%s' image with %s size to STM32MP_UBI_VOLUME." % (items[0], items[3]))
                            d.appendVar('STM32MP_UBI_VOLUME', ' ' + items[0] + ':' + items[3])

                    else:
                        bb.fatal('[PARTITIONS_CONFIG] Missing image setting')

                    break

    # Reset IMAGE_LIST_SUMMARY with computed partition configuration
    if d.getVar('ENABLE_IMAGE_LICENSE_SUMMARY') == "1":
        bb.debug(1, "Set IMAGE_SUMMARY_LIST with configuration: %s." % image_summary_list)
        d.setVar('IMAGE_SUMMARY_LIST', image_summary_list)

    # Init partition list from PARTITIONS_IMAGE
    image_partitions = (d.getVar('PARTITIONS_IMAGE') or "").split()
    # -----------------------------------------------------------------------------
    # Make sure to append the partition build to current image target
    # -----------------------------------------------------------------------------
    if len(image_partitions) > 0:
        # Gather all current tasks
        tasks = filter(lambda k: d.getVarFlag(k, "task", True), d.keys())
        for task in tasks:
            # Check that we are dealing with image recipe
            if task == 'do_image_complete':
                # Init current image name
                current_image_name = d.getVar('PN') or ""
                # Init RAMFS image if any
                initramfs = d.getVar('INITRAMFS_IMAGE') or ""
                # Init INITRD image if any
                initrd = d.getVar('INITRD_IMAGE') or ""
                # We need to append partition images generation only to image
                # that are not one of the defined partitions and not the InitRAMFS image.
                # Without this check we would create circular dependency
                if current_image_name not in image_partitions and current_image_name != initramfs and current_image_name != initrd:
                    for partition in image_partitions:
                        bb.debug(1, "Appending %s image build to 'do_image_complete' depends tasks." % partition)
                        d.appendVarFlag('do_image_complete', 'depends', ' %s:do_image_complete' % partition)
                    bb.debug(1, "Appending 'image_rootfs_image_clean_task' to IMAGE_PREPROCESS_COMMAND.")
                    d.appendVar('IMAGE_PREPROCESS_COMMAND', 'image_rootfs_image_clean_task;')
                    # Manage multiubi volume build enable for current image
                    if bb.utils.contains('IMAGE_FSTYPES', 'stmultiubi', True, False, d) and d.getVar('ENABLE_MULTIVOLUME_UBI') == "1":
                        bb.debug(1, "Appending 'st_multivolume_ubifs' to IMAGE_POSTPROCESS_COMMAND.")
                        d.appendVar('IMAGE_POSTPROCESS_COMMAND', 'st_multivolume_ubifs;')
}

image_rootfs_image_clean_task() {
    bbnote "PARTITIONS_IMAGE"
    bbnote ">>> ${PARTITIONS_IMAGE}"
    bbnote "PARTITIONS_MOUNTPOINT"
    bbnote ">>> ${PARTITIONS_MOUNTPOINT}"
    unset i j
    for img in ${PARTITIONS_IMAGE}; do
        i=$(expr $i + 1);
        for part in ${PARTITIONS_MOUNTPOINT}; do
            j=$(expr $j + 1);
            if [ $j -eq $i ]; then
                bbnote "Expecting to clean folder:"
                bbnote ">>> ${IMAGE_ROOTFS}/$part"
                if [ -d ${IMAGE_ROOTFS}/$part ]; then
                    rm -rf ${IMAGE_ROOTFS}/$part/*
                    bbnote ">>> DONE"
                else
                    bbnote ">>> NOT DONE : $part folder doesn't exist in image rootfs"
                fi
            fi
        done
        unset j
    done
    unset i
}

st-partitions-image.bbclass 整个文件看起来比较长,其实里面大部分都是调试日志。 总共有几部分组成:

  1. 重要的三个变量
    ENABLE_PARTITIONS_IMAGE:用来控制是否使能生成分区镜像,在镜像bb文件中可以覆盖此变量控制该class的功能
    PARTITIONS_CONFIG:设置的分区配置
    PARTITIONS_IMAGE:分区镜像的名字
    PARTITIONS_MOUNTPOINT:分区镜像的挂载点

  2. 一个匿名函数
    以PARTITIONS_CONFIG 为输入,PARTITIONS_IMAGE 和PARTITIONS_MOUNTPOINT 为输出
    通过bitbake -e fs-mp1a-qt可以先看一下最终的变量值:

PARTITIONS_CONFIG=" bootfs vendorfs rootfs userfs"
//PARTITIONS_CONFIG[xxxfs] 字段含义
// "${STM32MP_XXFS_IMAGE},${STM32MP_XXFS_LABEL},${STM32MP_XXFS_MOUNTPOINT},${XXFS_PARTITION_SIZE},System"

PARTITIONS_CONFIG[bootfs]      ?= "st-image-bootfs,boot,/boot,65536,System"
PARTITIONS_CONFIG[vendorfs] ?= "st-image-vendorfs,vendorfs,/vendor,16384,FileSystem"
PARTITIONS_CONFIG[rootfs]       ?= "fs-mp1a-qt-openstlinux-eglfs,rootfs,1253376,FileSystem"
PARTITIONS_CONFIG[userfs]       ?= "st-image-userfs,userfs,/usr/local,131072,FileSystem"

PARTITIONS_IMAGE=" st-image-bootfs st-image-vendorfs st-image-userfs"
PARTITIONS_MOUNTPOINT=" /boot /vendor /usr/local"

下面详细分析python __anonymous是怎么处理的:
输入变量PARTITIONS_CONFIG:
PARTITIONS_CONFIG=" bootfs vendorfs rootfs userfs"
PARTITIONS_CONFIG[bootfs] ?= “st-image-bootfs,boot,/boot,65536,System”
PARTITIONS_CONFIG[vendorfs] ?= “st-image-vendorfs,vendorfs,/vendor,16384,FileSystem”
PARTITIONS_CONFIG[rootfs] ?= “fs-mp1a-qt-openstlinux-eglfs,rootfs,1253376,FileSystem”
PARTITIONS_CONFIG[userfs] ?= “st-image-userfs,userfs,/usr/local,131072,FileSystem”

partitionsconfigflags:
bootfs “st-image-bootfs,boot,/boot,65536,System”
vendorfs “st-image-vendorfs,vendorfs,/vendor,16384,FileSystem”
rootfs “fs-mp1a-qt-openstlinux-eglfs,rootfs,1253376,FileSystem”
userfs “st-image-userfs,userfs,/usr/local,131072,FileSystem”

partitionsconfig:
bootfs vendorfs rootfs userfs

        for config in partitionsconfig:
            for f, v in partitionsconfigflags.items():
                if config == f:
                    items = v.split(',')

上面这段判断可以知道(以第一个bootfs为例) items= {st-image-bootfs boot /boot 65536 System }

                        if len(items) > 2 and items[2]:
                            # Mount point available, so we're dealing with partition image
                            # PARTITIONS_IMAGE appending
                            bb.debug(1, "Appending '%s' to PARTITIONS_IMAGE." % items[0])
                            d.appendVar('PARTITIONS_IMAGE', ' ' + items[0])
                            # PARTITIONS_MOUNTPOINT appending
                            bb.debug(1, "Appending '%s' to PARTITIONS_MOUNTPOINT." % items[2])
                            d.appendVar('PARTITIONS_MOUNTPOINT', ' ' + items[2])

如果items大于2且items[2]存在,则
PARTITIONS_IMAGE += items[0] //items[0] = st-image-bootfs
PARTITIONS_MOUNTPOINT += items[2] //items[2] = /boot

如此循环下来:
PARTITIONS_IMAGE =" st-image-bootfs st-image-vendorfs fs-mp1a-qt-openstlinux-eglfs st-image-userfs"
PARTITIONS_MOUNTPOINT=" /boot /vendor rootfs /usr/local"

这里PARTITIONS_MOUNTPOINT 和我们通过实际bitbake -e看到的环境变量对不上,我们接着往下分析

                        # Update IMAGE vars for each partition image
                        if items[1]:
                            bb.debug(1, "Set UBI_VOLNAME to %s for %s partition image." % (items[1], items[0]))
                            d.setVar('UBI_VOLNAME_pn-%s' % d.expand(items[0]), items[1])
                            if d.expand(items[1])[-2:] != 'fs':
                                bb.debug(1, "Set IMAGE_NAME_SUFFIX to '.%sfs' for %s partition image." % (items[1], items[0]))
                                d.setVar('IMAGE_NAME_SUFFIX_pn-%s' % d.expand(items[0]), '.' + items[1] + 'fs')
                            else:
                                bb.debug(1, "Set IMAGE_NAME_SUFFIX to '.%s' for %s partition image." % (items[1], items[0]))
                                d.setVar('IMAGE_NAME_SUFFIX_pn-%s' % d.expand(items[0]), '.' + items[1])
                        else:
                            bb.fatal('[PARTITIONS_CONFIG] Missing label setting for %s image' % items[0])
                        if items[2]:
                            bb.debug(1, "Set IMAGE_PARTITION_MOUNTPOINT to %s for %s partition image." % (items[2], items[0]))
                            d.setVar('IMAGE_PARTITION_MOUNTPOINT_pn-%s' % d.expand(items[0]), items[2])
                        if items[3]:
                            bb.debug(1, "Set IMAGE_ROOTFS_SIZE to %s for %s partition image." % (items[3], items[0]))
                            d.setVar('IMAGE_ROOTFS_SIZE_pn-%s' % d.expand(items[0]), items[3])
                        else:
                            bb.fatal('[PARTITIONS_CONFIG] Missing size setting for %s image' % items[0])
  • 如果items[1]存在(以第一个bootfs为例)
    UBI_VOLNAME_pn-st-image-bootfs=/boot
  • 如果items[1]的最后2位不是fs结尾则手动添加fs结尾以后设置IMAGE_NAME_SUFFIX_pn变量
    IMAGE_NAME_SUFFIX_pn-st-image-bootfs=.boot
  • 如果items[2]存在
    IMAGE_PARTITION_MOUNTPOINT_pn-st-image-bootfs=/boot
  • 如果items[3]存在
    IMAGE_ROOTFS_SIZE_pn-st-image-bootfs=65536
                        # Manage IMAGE_SUMMARY_LIST configuration according to PARTITION_CONFIG set
                        if d.getVar('ENABLE_IMAGE_LICENSE_SUMMARY') == "1":
                            if not items[2]:
                                # Set '/' as default mountpoint for rootfs in IMAGE_SUMMARY_LIST
                                items[2] = '/'
                            image_summary_list += items[0] + ':' + items[2] + ';'

                        # Manage multiubi volume list STM32MP_UBI_VOLUME
                        if bb.utils.contains('IMAGE_FSTYPES', 'stmultiubi', True, False, d) and d.getVar('ENABLE_MULTIVOLUME_UBI') == "1":
                            bb.debug(1, "Appending '%s' image with %s size to STM32MP_UBI_VOLUME." % (items[0], items[3]))
                            d.appendVar('STM32MP_UBI_VOLUME', ' ' + items[0] + ':' + items[3])
                           
    # Reset IMAGE_LIST_SUMMARY with computed partition configuration
    if d.getVar('ENABLE_IMAGE_LICENSE_SUMMARY') == "1":
        bb.debug(1, "Set IMAGE_SUMMARY_LIST with configuration: %s." % image_summary_list)
        d.setVar('IMAGE_SUMMARY_LIST', image_summary_list)
  • 如果环境变量ENABLE_IMAGE_LICENSE_SUMMARY被设置
    image_summary_list += st-image-bootfs:/boot;
    循环下来image_summary_list=“st-image-bootfs:/boot;st-image-vendorfs:/vendor;fs-mp1a-qt-openstlinux-eglfs:rootfs;st-image-userfs:/usr/local;”
    IMAGE_SUMMARY_LIST = image_summary_list

  • 如果IMAGE_FSTYPES 中包含stmultiubi类型且ENABLE_MULTIVOLUME_UBI变量被设置
    STM32MP_UBI_VOLUME +=" st-image-bootfs:65536"
    循环下来STM32MP_UBI_VOLUME=" st-image-bootfs:65536 st-image-vendorfs:16384 fs-mp1a-qt-openstlinux-eglfs:1253376 st-image-userfs:131072"

这里循环结束,总结一下设置了哪些变量:
PARTITIONS_IMAGE =" st-image-bootfs st-image-vendorfs fs-mp1a-qt-openstlinux-eglfs st-image-userfs"
PARTITIONS_MOUNTPOINT=" /boot /vendor rootfs /usr/local"

UBI_VOLNAME_pn-st-image-bootfs=/boot
IMAGE_NAME_SUFFIX_pn-st-image-bootfs=.boot
IMAGE_PARTITION_MOUNTPOINT_pn-st-image-bootfs=/boot
IMAGE_ROOTFS_SIZE_pn-st-image-bootfs=65536

IMAGE_SUMMARY_LIST=“st-image-bootfs:/boot;st-image-vendorfs:/vendor;fs-mp1a-qt-openstlinux-eglfs:rootfs;st-image-userfs:/usr/local;”
STM32MP_UBI_VOLUME=" st-image-bootfs:65536 st-image-vendorfs:16384 fs-mp1a-qt-openstlinux-eglfs:1253376 st-image-userfs:131072"

继续分析

    image_partitions = (d.getVar('PARTITIONS_IMAGE') or "").split()
    if len(image_partitions) > 0:
        # Gather all current tasks
        tasks = filter(lambda k: d.getVarFlag(k, "task", True), d.keys())
        for task in tasks:
            # Check that we are dealing with image recipe
            if task == 'do_image_complete':
                # Init current image name
                current_image_name = d.getVar('PN') or ""
                # Init RAMFS image if any
                initramfs = d.getVar('INITRAMFS_IMAGE') or ""
                # Init INITRD image if any
                initrd = d.getVar('INITRD_IMAGE') or ""
                # We need to append partition images generation only to image
                # that are not one of the defined partitions and not the InitRAMFS image.
                # Without this check we would create circular dependency
                if current_image_name not in image_partitions and current_image_name != initramfs and current_image_name != initrd:
                    for partition in image_partitions:
                        bb.debug(1, "Appending %s image build to 'do_image_complete' depends tasks." % partition)
                        d.appendVarFlag('do_image_complete', 'depends', ' %s:do_image_complete' % partition)
                    bb.debug(1, "Appending 'image_rootfs_image_clean_task' to IMAGE_PREPROCESS_COMMAND.")
                    d.appendVar('IMAGE_PREPROCESS_COMMAND', 'image_rootfs_image_clean_task;')
                    # Manage multiubi volume build enable for current image
                    if bb.utils.contains('IMAGE_FSTYPES', 'stmultiubi', True, False, d) and d.getVar('ENABLE_MULTIVOLUME_UBI') == "1":
                        bb.debug(1, "Appending 'st_multivolume_ubifs' to IMAGE_POSTPROCESS_COMMAND.")
                        d.appendVar('IMAGE_POSTPROCESS_COMMAND', 'st_multivolume_ubifs;')

image_partitions = [“st-image-bootfs”, “st-image-vendorfs”, “fs-mp1a-qt-openstlinux-eglfs”, “st-image-userfs” ]
找到所有非initramfs 、initrd和 image_partitions中包含的image 的 do_image_complete的task,设置他们的依赖:
do_image_complete[depends] = st-image-bootfs:do_image_complete
do_image_complete[depends] = st-image-vendorfs:do_image_complete
do_image_complete[depends] = fs-mp1a-qt-openstlinux-eglfs:do_image_complete
do_image_complete[depends] = st-image-userfs:do_image_complete
IMAGE_POSTPROCESS_COMMAND+=st_multivolume_ubifs
到这里,可以看到所有的iamge 菜谱生成进行必须先等image_partitions 中的镜像生成以后才可以生成。

这部分分析结束,还有个疑问:bitbake中的变量里面没有rootfs相关的设置,但是分析下来是有的,这里等后续image生成流程都分析完了在回头看看是不是那里过滤掉了。
PARTITIONS_IMAGE=" st-image-bootfs st-image-vendorfs st-image-userfs"
PARTITIONS_MOUNTPOINT=" /boot /vendor /usr/local"

PARTITIONS_IMAGE =" st-image-bootfs st-image-vendorfs fs-mp1a-qt-openstlinux-eglfs st-image-userfs"
PARTITIONS_MOUNTPOINT=" /boot /vendor rootfs /usr/local"

  1. 一个 task
    image_rootfs_image_clean_task

最后还生名了一个task,里面比较简单:

    for img in ${PARTITIONS_IMAGE}; do
        i=$(expr $i + 1);
        for part in ${PARTITIONS_MOUNTPOINT}; do
            j=$(expr $j + 1);
            if [ $j -eq $i ]; then
                bbnote "Expecting to clean folder:"
                bbnote ">>> ${IMAGE_ROOTFS}/$part"
                if [ -d ${IMAGE_ROOTFS}/$part ]; then
                    rm -rf ${IMAGE_ROOTFS}/$part/*
                    bbnote ">>> DONE"
                else
                    bbnote ">>> NOT DONE : $part folder doesn't exist in image rootfs"
                fi
            fi
        done
        unset j
    done

最终效果就是把tmp-glibc/work/fsmp1a-ostl-linux-gnueabi/fs-mp1a-qt/1.0-r0/rootfs/boot/*删除(以bootfs为例)

DONE

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

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

相关文章

「UWB」精准定位黑科技,开启座舱雷达新蓝海

基于厘米级定位、超低功率、强抗干扰、超大容量等技术特点,UWB(超宽带)技术在消费电子、智能汽车等领域的应用前景被赋予厚望。 值得一提的是,利用UWB雷达还可实现舱内活体检测、脚踢尾箱等,这意味着新一轮座舱感知革…

【Vue】ref引用,插槽

一、ref 什么是ref? ref用来辅助开发者在不依赖于jQuery 的情况下,获取DOM元素或组件的引用。 每个vue的组件实例上,都包含一个$refs对象,里面存储着对应的DOM元素或组件的引用。默认情况下,组件的$refs 指向一个空对…

Ubuntu20.04下安装nvidia驱动

ubuntu-drivers devices会显示你的电脑上可用的nvidia驱动。只需要安装推荐的版本即可(后面有recommend字样) 打开电脑里的软件和更新app(这里建议换提前换源,阿里源或者清华源) 来到附加驱动这个页面,选…

HTML初识-概念和基本知识

1 . HTML初识-基础认知 HTML标签 1.1 目录 ◆ 基础认知 ◆ HTML标签学习 ◆ 综合案例 1.2 学习目标 ◆ 能够理解HTML的 基本语法 和标签的关系 ◆ 能够使用 排版标签 实现网页中标题、段落等效果 ◆ 能够使用 相对路径 选择不同目录下的文件 ◆ 能够使用 媒体标签 在网页中显示…

ES进阶教程

1.分片Shards 一个索引可以存储超出单个结点硬件限制的大量数据,es提供了将索引划分为多份的能力,每一份都称之为分片.当创建索引时,可以指定想要的分片数量.每个分片本身也是一个功能完善并且相对独立的索引.这个索引可以被放在集群中的任何结点上. 分片的重要性 1.允许水平切…

相控阵天线(九):平面阵列天线综合(不可分离型切比雪夫分布、圆口径泰勒综合、可分离型分布、配相抵消法)

目录简介不可分离型分布不可分离型切比雪夫圆口径泰勒综合可分离型分布可分离切比雪夫综合可分离泰勒综合平面阵列配相抵消法简介 按行、列排列的可分离型矩形平面阵,其阵因子是两个正交排列的直线阵阵因子的乘积。可分离的平面阵方向图在两个主面内是满足预期副瓣…

Docker创建Spring容器【方便服务迁移】

📃目录跳转📚简介:🎃 1.上传jar包🎉2.创建Dockerfile文件🗺️3.生成容器🍥4.查看本地镜像🚀5.运行镜像🔭6.使用工具访问接口🏆总结📚简介&#xf…

网上预约挂号系统的设计与实现

项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下,你想解决的问…

si9000 单端(线)差分(动)线板层结构与阻抗计算

常见的单端(线)阻抗计算模式: Surface Microstrip 1B 在下图(表面,或暴露,微带)信号线暴露(空气)和参考电源或接地平面。根据电介质相对于迹的排列(在迹的下方或上方)对结构进行分类。下图显示了在信号轨迹(指定为1B)以下使用单一介电层的表…

elasticsearch数据存储结构,springboot集成elasticsearch

一、数据存储结构 结合数据库的结构理解起来就会比较清楚: 1)索引(Index)>数据库(Database)。 2)类型(Type)>表(Table)。 3)文档…

Ubuntu 20.04.05安装PCL-1.12.0

1、安装QT-5.9.9 链接: Ubuntu20.04安装、配置、使用、卸载QT5.9.9以及第一个编写QT程序. 或者 链接: 在ubuntu用命令安装和卸载qt4、qt5(亲测有效). 2、安装VTK-7.1.1PCL-1.12.0 链接: ubuntu20.04下安装pcl. 或者 链接: PCL1.12VTK7.1.1 && Ubuntu20.04.3VSCode(官…

Python一炮句搞定网页登录验证码自动输入

前言:本来是“账号密码”的登录方式,突然就增加了验证码输入,还30秒一变。 查看元素 链接为一个png图片文件,每半分钟一更新,意思就是慢了还不行。 思路:OCR识别图片中的…

【并发】Java并发线程池底层原理详解与源码分析(下)

【并发】Java并发线程池底层原理详解与源码分析(下) 前情回顾 上篇文章地址 【并发】Java并发线程池底层原理详解与源码分析(上)_面向鸿蒙编程的博客-CSDN博客线程池不允许使用 Executors 去创建,而是通过 ThreadPo…

浅析数据迁移工具Sqoop

title: Sqoop系列 第一章 Sqoop理论 1.1 概述 sqoop 是 apache 旗下一款“Hadoop 和关系数据库服务器之间传送数据”的工具。 导入(Import)数据:MySQL,Oracle 导入数据到 Hadoop 的 HDFS、HIVE、HBASE 等数据存储系统 导出&…

八、Gateway

文章目录一、Gateway网关1.网关的作用二、配置网关1.创建gateway模块2.引入依赖3.编写application.yml4.启动gateway模块,查看是否能访问user-service服务三、路由断言工厂Route Predicate Factory四、GatewayFilter(过滤器)1.添加过滤器方式…

IDEA2022用maven创建的Servlet项目

因为博主太菜太笨,总是记不住大佬教的步骤,写一篇博客记录一下。 有什么不对,或者疑惑可以请假这位大佬(没错就是那个被我问烦的大佬)ljj大佬 第一步:新建maven 新建Project 选择webapp 初始界面需要等待…

S32K144之ADC

一,S32K144的ADC介绍 1,ADC模块特性 S32K14x和S32K14xW包含两个12位ADC模块,ADC0和ADC1。 S32K11x包含一个12位的ADC模块,ADC0。 不同封装,ADC0和ADC1所包含的通道数不一样,LQFP100来说ADC0和ADC1分别有16…

Spark - RDD 算子介绍及使用 Scala、Java、Python 三种语言演示

一、RDD 的起源 在 RDD 出现之前, 当时 MapReduce 是比较主流的, 而 MapReduce 如何执行流程如下: 多个 MapReduce 任务之间只能通过磁盘来进行传递数据,很明显的效率低下,再来看 RDD 的处理方式: 整个过程是共享内存的, 而不需…

利用pycharm调试ssh远程程序,并实时同步文件

或许你的服务器由于设置问题,不能通过Vscode进行远程调试python程序,那么本篇文章提供了利用pycharm远程调试程序的方法,且使用的编译器可以是服务器中的虚拟环境的编译器,可以实时同步本地与服务器的文件内容。希望对你能够有所帮…

【Oracle系列1】Oracle 的connect权限和create session的区别

【Oracle系列1】Oracle 的connect权限和create session的区别 背景 oracle数据库新建用户之后是无法登录的,需要赋予connect角色或者create session权限。 注意: connect是角色不是权限,create session是权限不是角色。角色是权限的集合。…