ov2640子设备视频操作详细分析

ov2640子设备视频操作详细分析


文章目录

  • ov2640子设备视频操作详细分析
  • ov2640_subdev_video_ops视频操作
  • ov2640_s_stream开始流
  • ov2640_g_fmt 获取格式
  • ov2640_s_fmt设置格式
  • ov2640_try_fmt尝试格式
  • ov2640_cropcap裁剪能力
  • ov2640_g_crop获取裁剪
  • ov2640_enum_fmt枚举格式
  • ov2640_g_mbus_config获取总线配置


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

ov2640_subdev_video_ops视频操作

这段代码定义了一个名为ov2640_subdev_video_ops的结构体变量,该变量是struct v4l2_subdev_video_ops类型的,用于配置与视频子设备相关的操作。
这个结构体包含了多个成员函数,每个函数都对应一个特定的操作:
.s_stream: 用于开始流传输的函数,对应的函数名是ov2640_s_stream。
.g_mbus_fmt: 用于获取当前视频格式的函数,对应的函数名是ov2640_g_fmt。
.s_mbus_fmt: 用于设置视频格式的函数,对应的函数名是ov2640_s_fmt。
.try_mbus_fmt: 用于尝试设置视频格式的函数,对应的函数名是ov2640_try_fmt。
.cropcap: 用于获取视频裁剪能力的函数,对应的函数名是ov2640_cropcap。
.g_crop: 用于获取当前裁剪设置的函数,对应的函数名是ov2640_g_crop。
.enum_mbus_fmt: 用于枚举支持的视频格式的函数,对应的函数名是ov2640_enum_fmt。
.g_mbus_config: 用于获取总线配置的函数,对应的函数名是ov2640_g_mbus_config。
这些成员函数定义了视频子设备操作的行为,通过指定相应的函数名,可以在需要时调用对应的操作函数进行处理。

static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
    .s_stream    = ov2640_s_stream, // 开始流
    .g_mbus_fmt    = ov2640_g_fmt, // 获取格式
    .s_mbus_fmt    = ov2640_s_fmt, // 设置格式
    .try_mbus_fmt    = ov2640_try_fmt, // 尝试格式
    .cropcap    = ov2640_cropcap, // 裁剪能力
    .g_crop        = ov2640_g_crop, // 获取裁剪
    .enum_mbus_fmt    = ov2640_enum_fmt, // 枚举格式
    .g_mbus_config    = ov2640_g_mbus_config, // 获取总线配置
};

ov2640_s_stream开始流

ov2640_g_fmt 获取格式

这段代码是用于获取 OV2640 摄像头的格式信息的函数。它的作用是更新给定的 struct v4l2_mbus_framefmt 结构体 mf 中的宽度、高度、格式和颜色空间等字段。
函数首先通过 struct v4l2_subdev 结构体指针 sd 获取对应的 struct i2c_client 结构体指针 client,然后通过 to_ov2640 宏将 client 转换为 struct ov2640_priv 结构体指针 priv。
如果 priv->win 指针为空,表示窗口尺寸还没有被选择,则设置默认的宽度为 SVGA_WIDTH,默认的高度为 SVGA_HEIGHT,并通过 ov2640_select_win 函数选择窗口大小,并将返回的窗口信息保存在 priv->win 中,并初始化 priv->cfmt_code 为 MEDIA_BUS_FMT_UYVY8_2X8。
接下来,将 mf 的宽度和高度更新为 priv->win 中的宽度和高度,将 mf->code 更新为 priv->cfmt_code,表示当前的图像格式。根据图像格式的不同,将 mf->colorspace 设置为对应的颜色空间,如果是 MEDIA_BUS_FMT_RGB565_2X8_BE 或 MEDIA_BUS_FMT_RGB565_2X8_LE 格式,则选择 SRGB 颜色空间,否则选择 JPEG 颜色空间。最后,将 mf->field 设置为 V4L2_FIELD_NONE,表示没有场标志。
最后,函数返回 0,表示成功获取格式信息。

// 获取ov2640的格式
static int ov2640_g_fmt(struct v4l2_subdev *sd,
            struct v4l2_mbus_framefmt *mf)
{
    struct i2c_client  *client = v4l2_get_subdevdata(sd); // 获取i2c_client结构体
    struct ov2640_priv *priv = to_ov2640(client); // 获取ov2640_priv结构体

    if (!priv->win) { // 如果win指针为空
        u32 width = SVGA_WIDTH, height = SVGA_HEIGHT; // 定义width和height变量并初始化
        priv->win = ov2640_select_win(&width, &height); // 选择窗口大小
        priv->cfmt_code = MEDIA_BUS_FMT_UYVY8_2X8; // 初始化cfmt_code为UYVY8_2X8
    }

    mf->width    = priv->win->width; // 更新宽度
    mf->height    = priv->win->height; // 更新高度
    mf->code    = priv->cfmt_code; // 更新格式

    switch (mf->code) { // 根据格式选择颜色空间
    case MEDIA_BUS_FMT_RGB565_2X8_BE:
    case MEDIA_BUS_FMT_RGB565_2X8_LE:
        mf->colorspace = V4L2_COLORSPACE_SRGB; // 选择SRGB颜色空间
        break;
    default:
    case MEDIA_BUS_FMT_YUYV8_2X8:
    case MEDIA_BUS_FMT_UYVY8_2X8:
        mf->colorspace = V4L2_COLORSPACE_JPEG; // 选择JPEG颜色空间
    }
    mf->field    = V4L2_FIELD_NONE; // 设置field为NONE

    return 0; // 返回0
}

ov2640_s_fmt设置格式

这段代码是用于设置 OV2640 摄像头的格式的函数。它的作用是根据给定的 struct v4l2_mbus_framefmt 结构体 mf 中的格式字段,选择对应的颜色空间,并将格式和尺寸参数传递给 ov2640_set_params 函数进行设置。
函数首先通过 struct v4l2_subdev 结构体指针 sd 获取对应的 struct i2c_client 结构体指针 client。
接下来,根据 mf->code 的值,选择相应的颜色空间。如果 mf->code 是 MEDIA_BUS_FMT_RGB565_2X8_BE 或 MEDIA_BUS_FMT_RGB565_2X8_LE,则选择 SRGB 颜色空间;否则,将 mf->code 更新为 MEDIA_BUS_FMT_UYVY8_2X8,并选择 JPEG 颜色空间。
最后,调用 ov2640_set_params 函数,将 client、mf->width、mf->height 和 mf->code 作为参数传递给它,用于设置 OV2640 摄像头的参数。函数将 ov2640_set_params 的返回值作为自己的返回值,表示设置结果。
函数最终返回 ret,表示设置 OV2640 摄像头的结果

// 设置ov2640的格式
static int ov2640_s_fmt(struct v4l2_subdev *sd,
            struct v4l2_mbus_framefmt *mf)
{
    struct i2c_client *client = v4l2_get_subdevdata(sd); // 获取i2c_client结构体
    int ret;

    // 根据格式选择颜色空间
    switch (mf->code) {
    case MEDIA_BUS_FMT_RGB565_2X8_BE:
    case MEDIA_BUS_FMT_RGB565_2X8_LE:
        mf->colorspace = V4L2_COLORSPACE_SRGB; // 选择SRGB颜色空间
        break;
    default:
        mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
    case MEDIA_BUS_FMT_YUYV8_2X8:
    case MEDIA_BUS_FMT_UYVY8_2X8:
        mf->colorspace = V4L2_COLORSPACE_JPEG; // 选择JPEG颜色空间
    }

    ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code); // 设置ov2640的参数

    return ret; // 返回设置结果
}

这段代码是用于设置 OV2640 摄像头的参数的函数。它接受 struct i2c_client 结构体指针 client、u32 类型的指针 width 和 height,以及一个 u32 类型的参数 code。
函数首先通过 struct i2c_client 结构体指针 client 获取对应的 struct ov2640_priv 结构体指针 priv。
接下来,根据给定的 code 值选择相应的格式,并将选择的格式的寄存器列表赋值给 selected_cfmt_regs 指针。根据不同的 code 值,输出相应的调试信息。
然后,调用 ov2640_reset 函数重置硬件。
接着,使用默认数据初始化传感器,调用 ov2640_write_array 函数将默认数据写入摄像头寄存器。如果写入过程中出现错误,将跳转到 err 标签处进行错误处理。
然后,选择前导码,将窗口大小和格式的前导码写入摄像头寄存器。
接下来,根据选定的格式,调用 ov2640_write_array 函数将相应格式的寄存器列表写入摄像头寄存器。
最后,更新 priv->cfmt_code 的值为 code,将 width 和 height 更新为选定窗口的宽度和高度,并返回 0 表示设置成功。
如果在设置过程中出现错误,将输出相应的错误信息,重置硬件,将 priv->win 指针置为 NULL,并返回错误码。

// 设置ov2640的参数
static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height,
                 u32 code)
{
    struct ov2640_priv       *priv = to_ov2640(client); // 获取ov2640_priv结构体
    const struct regval_list *selected_cfmt_regs; // 定义selected_cfmt_regs指针
    int ret;

    /* select win */ // 选择窗口大小
    priv->win = ov2640_select_win(width, height); // 选择窗口大小

    /* select format */ // 选择格式
    priv->cfmt_code = 0; // 初始化cfmt_code为0
    switch (code) { // 根据code选择格式
    case MEDIA_BUS_FMT_RGB565_2X8_BE:
        dev_dbg(&client->dev, "%s: Selected cfmt RGB565 BE", __func__); // 输出调试信息
        selected_cfmt_regs = ov2640_rgb565_be_regs; // 选择RGB565 BE格式
        break;
    case MEDIA_BUS_FMT_RGB565_2X8_LE:
        dev_dbg(&client->dev, "%s: Selected cfmt RGB565 LE", __func__); // 输出调试信息
        selected_cfmt_regs = ov2640_rgb565_le_regs; // 选择RGB565 LE格式
        break;
    case MEDIA_BUS_FMT_YUYV8_2X8:
        dev_dbg(&client->dev, "%s: Selected cfmt YUYV (YUV422)", __func__); // 输出调试信息
        selected_cfmt_regs = ov2640_yuyv_regs; // 选择YUYV格式
        break;
    default:
    case MEDIA_BUS_FMT_UYVY8_2X8:
        dev_dbg(&client->dev, "%s: Selected cfmt UYVY", __func__); // 输出调试信息
        selected_cfmt_regs = ov2640_uyvy_regs; // 选择UYVY格式
    }


    /* 重置硬件 */
    ov2640_reset(client);

    /* 使用默认数据初始化传感器 */
    dev_dbg(&client->dev, "%s: Init default", __func__);
    ret = ov2640_write_array(client, ov2640_init_regs); // 写入默认数据
    if (ret < 0)
        goto err;

    /* 选择前导码 */
    dev_dbg(&client->dev, "%s: Set size to %s", __func__, priv->win->name);
    ret = ov2640_write_array(client, ov2640_size_change_preamble_regs); // 写入前导码
    if (ret < 0)
        goto err;

    /* 设置窗口大小 */
    ret = ov2640_write_array(client, priv->win->regs); // 写入窗口大小
    if (ret < 0)
        goto err;

    /* 格式前导码 */
    dev_dbg(&client->dev, "%s: Set cfmt", __func__);
    ret = ov2640_write_array(client, ov2640_format_change_preamble_regs); // 写入格式前导码
    if (ret < 0)
        goto err;

    /* 设置格式 */
    ret = ov2640_write_array(client, selected_cfmt_regs); // 写入选择的格式
    if (ret < 0)
        goto err;

    priv->cfmt_code = code; // 更新cfmt_code
    *width = priv->win->width; // 更新宽度
    *height = priv->win->height; // 更新高度

    return 0; // 返回0

err:
    dev_err(&client->dev, "%s: Error %d", __func__, ret); // 输出错误信息
    ov2640_reset(client); // 重置硬件
    priv->win = NULL; // 将win指针置为NULL

    return ret; // 返回错误码
}

ov2640_try_fmt尝试格式

这段代码是用于尝试设置 OV2640 摄像头的格式的函数。它接受 struct v4l2_subdev 结构体指针 sd 和 struct v4l2_mbus_framefmt 结构体指针 mf。
函数首先调用 ov2640_select_win 函数选择合适的窗口大小,并更新 mf->width 和 mf->height 的值,但不存储窗口大小。
接下来,将 mf->field 设置为 V4L2_FIELD_NONE,表示字段顺序为无。
然后,根据给定的 mf->code 值选择相应的格式,并将选择的格式的颜色空间赋值给 mf->colorspace。根据不同的 mf->code 值,选择相应的颜色空间。
最后,返回 0 表示设置成功。
这个函数的作用是根据给定的格式代码 mf->code,尝试设置摄像头的格式,并更新颜色空间等相关信息。但它并不实际存储窗口大小,仅仅是进行格式的尝试。

static int ov2640_try_fmt(struct v4l2_subdev *sd,
              struct v4l2_mbus_framefmt *mf)
{
    // 选择合适的窗口大小,但不存储它
    ov2640_select_win(&mf->width, &mf->height);

    mf->field    = V4L2_FIELD_NONE;

    switch (mf->code) {
    case MEDIA_BUS_FMT_RGB565_2X8_BE:
    case MEDIA_BUS_FMT_RGB565_2X8_LE:
        mf->colorspace = V4L2_COLORSPACE_SRGB; // 选择SRGB颜色空间
        break;
    default:
        mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
    case MEDIA_BUS_FMT_YUYV8_2X8:
    case MEDIA_BUS_FMT_UYVY8_2X8:
        mf->colorspace = V4L2_COLORSPACE_JPEG; // 选择JPEG颜色空间
    }

    return 0; // 返回0

}

ov2640_cropcap裁剪能力

这段代码用于获取 OV2640 摄像头的裁剪能力。它接受 struct v4l2_subdev 结构体指针 sd 和 struct v4l2_cropcap 结构体指针 a。
函数设置 a 中的字段值,表示裁剪能力的边界、默认矩形、类型和像素宽高比。
具体设置如下:
bounds 表示裁剪的边界,左边界为 0,上边界为 0,宽度为 UXGA_WIDTH,高度为 UXGA_HEIGHT。
defrect 表示默认矩形,与边界相同。
type 表示类型为 V4L2_BUF_TYPE_VIDEO_CAPTURE,表示视频捕获类型。
pixelaspect 表示像素宽高比,分子和分母都为 1,表示宽高比为 1:1。
最后,函数返回 0,表示获取裁剪能力成功。
这个函数的作用是获取 OV2640 摄像头的裁剪能力,将能力信息存储在 struct v4l2_cropcap 结构体中。

/ 获取裁剪能力
static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
{
    a->bounds.left            = 0; // 左边界为0
    a->bounds.top            = 0; // 上边界为0
    a->bounds.width            = UXGA_WIDTH; // 宽度为UXGA_WIDTH
    a->bounds.height        = UXGA_HEIGHT; // 高度为UXGA_HEIGHT
    a->defrect            = a->bounds; // 默认矩形为bounds
    a->type                = V4L2_BUF_TYPE_VIDEO_CAPTURE; // 类型为V4L2_BUF_TYPE_VIDEO_CAPTURE
    a->pixelaspect.numerator    = 1; // 像素宽高比的分子为1
    a->pixelaspect.denominator    = 1; // 像素宽高比的分母为1

    return 0; // 返回0
}

ov2640_g_crop获取裁剪

这段代码用于获取 OV2640 摄像头的裁剪信息。它接受 struct v4l2_subdev 结构体指针 sd 和 struct v4l2_crop 结构体指针 a。
函数设置 a 中的字段值,表示裁剪的矩形区域和类型。
具体设置如下:
c 表示裁剪的矩形区域,左边界为 0,上边界为 0,宽度为 UXGA_WIDTH,高度为 UXGA_HEIGHT。
type 表示类型为 V4L2_BUF_TYPE_VIDEO_CAPTURE,表示视频捕获类型。
最后,函数返回 0,表示获取裁剪信息成功。
这个函数的作用是获取 OV2640 摄像头的当前裁剪信息,将信息存储在 struct v4l2_crop 结构体中。

// 获取裁剪信息
static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
{
    a->c.left    = 0; // 左边界为0
    a->c.top    = 0; // 上边界为0
    a->c.width    = UXGA_WIDTH; // 宽度为UXGA_WIDTH
    a->c.height    = UXGA_HEIGHT; // 高度为UXGA_HEIGHT
    a->type        = V4L2_BUF_TYPE_VIDEO_CAPTURE; // 类型为V4L2_BUF_TYPE_VIDEO_CAPTURE

    return 0; // 返回0
}

ov2640_enum_fmt枚举格式

这段代码是用于枚举 OV2640 摄像头支持的格式的函数。它接受 struct v4l2_subdev 结构体指针 sd、无符号整数 index 和 u32 指针 code。
函数首先检查 index 是否超出了数组 ov2640_codes 的大小,如果超出则返回无效参数错误 -EINVAL。
然后,将 code 设置为数组 ov2640_codes 中对应索引位置的值,即获取对应索引处的格式代码。
最后,返回 0 表示枚举成功。
这个函数的作用是根据给定的索引 index,枚举摄像头支持的格式,并将对应索引处的格式代码存储在 code 中。

// 枚举ov2640的格式
static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
               u32 *code)
{
    if (index >= ARRAY_SIZE(ov2640_codes)) // 如果索引超出数组大小
        return -EINVAL; // 返回无效参数错误

    *code = ov2640_codes[index]; // 将code设置为ov2640_codes数组中对应的值
return 0; // 返回0
}

ov2640_g_mbus_config获取总线配置

这段代码用于获取 OV2640 摄像头的总线配置信息。它接受 struct v4l2_subdev 结构体指针 sd 和 struct v4l2_mbus_config 结构体指针 cfg。
函数从 sd 中获取 i2c_client 结构体指针 client,然后通过 client 获取 soc_camera_subdev_desc 结构体指针 ssdd。
函数设置 cfg 中的字段值,表示总线配置的标志和类型。
具体设置如下:
flags 表示总线配置的标志,包括 V4L2_MBUS_PCLK_SAMPLE_RISING、V4L2_MBUS_MASTER、V4L2_MBUS_VSYNC_ACTIVE_HIGH、V4L2_MBUS_HSYNC_ACTIVE_HIGH 和 V4L2_MBUS_DATA_ACTIVE_HIGH。
type 表示总线配置的类型,设置为 V4L2_MBUS_PARALLEL。
最后,函数返回 0,表示获取总线配置信息成功。
这个函数的作用是获取 OV2640 摄像头的当前总线配置信息,将信息存储在 struct v4l2_mbus_config 结构体中。

// 获取总线配置
static int ov2640_g_mbus_config(struct v4l2_subdev *sd,
                struct v4l2_mbus_config *cfg)
{
    struct i2c_client *client = v4l2_get_subdevdata(sd); // 获取i2c_client
    struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); // 获取soc_camera_subdev_desc

    cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | // 设置cfg的flags
        V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
        V4L2_MBUS_DATA_ACTIVE_HIGH;
    cfg->type = V4L2_MBUS_PARALLEL; // 设置cfg的type
    cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); // 设置cfg的flags


	return 0; // 返回0
}
    

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

六级备考26天|CET-6|仔细阅读|考研英语2023年英语(一)|8:20~10:00

text1 4/5 text2 3/5 text3 2/5 text4 3/5 12/20 目录 text 1 1. 重点词汇 2. 原文 3. 题目 text 1 1. 重点词汇 sympathise / ˈsɪmpəθaɪz / vi.同情&#xff1b;吊唁&#xff1b;共鸣 &#xff08;等于 sympathize&#xff09; ener…

黑客入门教程从零基础入门到精通,看完这一篇就够了

学前感言: 1.这是一条坚持的道路,三分钟的热情可以放弃往下看了. 2.多练多想,不要离开了教程什么都不会了.最好看完教程自己独立完成技术方面的开发. 3.有时多google,baidu,我们往往都遇不到好心的大神,谁会无聊天天给你做解答. 4.遇到实在搞不懂的,可以先放放,以后再来解决…

Scrum的执行过程及产品Backlog梳理的目的、时间、内容

Scrum的迭代运行过程 产品Backlog梳理 目的&#xff1a; •对下个Sprint的需求进行需求细节梳理和精化&#xff0c;识别技术风险和依赖&#xff0c;完成估算和优先级排序。 时间&#xff1a; •本Sprint开始后第6天&#xff0c;2小时以内 。 内容&#xff1a; •理解需求…

手把手教你用Python调用彩云机器翻译API

一、引言 彩云这个小而美的机器翻译一直很低调&#xff0c;它让人眼前一亮的是之前我们分享的网页翻译插件&#xff0c;可以把外文网站翻译成英中对照的样式&#xff0c;便于我们学习。之前我们也写过文章介绍过&#xff1a; PythonFan&#xff1a;如何用Google翻译英文网页成…

PyTorch RNN的原理及其手写复现。

PyTorch RNN的原理及其手写复现。 0、前言代码实现记忆单元(考虑过去的信息)分类包括&#xff1a;1.RNN 2.GRU 3.LSTM模型类别&#xff1a;1.单向循环(左到右) 2.双向循环&#xff08;考虑未来信息&#xff09; 3.多层单向或双向循环优缺点应用场景具体公式 0、前言 先给出代码…

单位、家庭建筑物电气、电子设备防雷举措

前 言 在现实的学习、工作、生活中&#xff0c;有时会面对自然灾害、重特大事故、环境公害及人为破坏等突发事件&#xff0c;为了控制事故的发展&#xff0c;就不得不需要事先制定应急预案。那要怎么制定科学的应急预案呢﹖下面是小编为大家整理的单位、住宅建筑物、电子电气防…

如何搭建一个高效、可靠的积分商城系统?

互联网购物的普及&#xff0c;积分商城系统已经成为商家和消费者之间互动的一种常见方式。它不仅可以帮助商家增加品牌影响力&#xff0c;还可以提高顾客体验&#xff0c;从而增加销售额。下面就如何搭建一个高效、可靠的积分商城系统作一些简单介绍。 第一步&#xff1a;确定需…

DHTMLX Suite JS PRO 8.1.1 Crack

适用于现代 Web 应用程序的强大 JavaScript 小部件库 - DHTMLX 套件 用于创建现代用户界面的轻量级、快速且通用的 JavaScript/HTML5 UI 小部件库。 DHTMLX Suite 有助于推进 Web 开发和构建具有丰富功能的数据密集型应用程序。 DHTMLX Suite 是一个 UI 小部件库&#xff0c;用…

Spring Boot中使用Spring Batch处理批量任务

Spring Boot中使用Spring Batch处理批量任务 Spring Batch是Spring框架的一个模块&#xff0c;它提供了一组API和工具&#xff0c;用于处理批量任务。在本文中&#xff0c;我们将会介绍如何在Spring Boot中使用Spring Batch来处理批量任务。我们将会使用一个简单的示例来说明如…

Install Prometheus Monitoring On Kubernetes Cluster

目录 Node & Software & Docker Images Lists ​Prometheus introduction Download Kubernetes Prometheus Manifest Files Install Prometheus Monitoring Kubernetes Create a Namespace Create a Cluster Role And Binding It Create a Config Map Create…

二、CNNs网络架构-卷积分离网络架构

《A review of convolutional neural network architectures and their optimizations》论文指出AlexNet的优异性能证明了可以通过增加网络深度提高网络性能。随着网络层数的不断增加&#xff0c;不断增加的计算负担和不显著的性能提升使得更先进的网络架构成为另一个主要的研究…

搭建监控日志系统

在微服务或者集群架构中&#xff0c;一次请求的调用会跨多个服务&#xff08;web&#xff0c;mysql&#xff0c;feign等&#xff09;、多个模块&#xff08;用户模块&#xff0c;商品模块等&#xff09;、多个容器&#xff08;用户模块可能有多个实例&#xff09;&#xff0c;这…

Linux命令(21)之usermod

Linux命令之usermod 1.usermod介绍 usermod命令用来更改/etc/passwd或/etc/shadow文件下用户属性&#xff0c;包括但不限于shell类型、用户id&#xff0c;用户gid、家目录、锁定及解锁用户等等。 2.usermod用法 usermod [参数] [用户名] usermod常用参数 参数说明-u修改UID…

Restful接口开发与测试—接口测试

开发完接口&#xff0c;接下来我们需要对我们开发的接口进行测试。接口测试的方法比较多&#xff0c;使用接口工具或者Python来测试都可以&#xff0c;工具方面比如之前我们学习过的Postman或者Jmeter &#xff0c;Python脚本测试可以使用Requests unittest来测试。 测试思路…

四维轻云平台常见问题及解决方法

1、在地图中看不见加载的点云或倾斜摄影模型数据&#xff1f; 若点云或模型数据加载后&#xff0c;在地图中看不见&#xff0c;可能是地形的高度高于倾斜模型的高度&#xff0c;导致数据漂浮在空中或者在地形以下&#xff0c;可通过增加数据的移动值Y来调整点云或者模型数据的…

支付宝SDK接口调试- cpolar内网穿透工具实现公网地址调试(1)

文章目录 1.测试环境2.本地配置3. 内网穿透3.1 下载安装cpolar内网穿透3.2 创建隧道 4. 测试公网访问5. 配置固定二级子域名5.1 保留一个二级子域名5.2 配置二级子域名 6. 使用固定二级子域名进行访问 转发自cpolar内网穿透的文章&#xff1a;Java支付宝沙箱环境支付&#xff0…

16款ChatGPT工具,太炸裂了,收藏!

1.ChatGPT for google 一个浏览器插件&#xff0c;可搭配现有的搜索引擎来使用。 最大化搜索效率&#xff0c;对搜索体验的提升相当离谱&#xff1a; 安装完插件后&#xff0c;在搜索引擎搜索任何问题&#xff0c;都能获取两份答案。 左边是谷歌抓取的全网资源&#xff0c;右…

chatgpt赋能python:简介:什么是PythonShapiro?

简介&#xff1a;什么是Python Shapiro&#xff1f; Python Shapiro是一种用来进行正态性检验的工具&#xff0c;也就是说&#xff0c;它可以帮助我们检验一个给定的数据集是否符合正态分布的要求。它是从R语言中的Shapiro-Wilk测试方法改编而来的。 如何使用Python Shapiro&…

ELK 企业级日志分析系统

---------------------- ELK 概述 ---------------------------------------- 1、ELK 简介 ELK平台是一套完整的日志集中处理解决方案&#xff0c;将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用&#xff0c; 完成更强大的用户对日志的查询、排序、统计需求。 ●…

1123 Is It a Complete AVL Tree (PAT甲级)

这道题是看了柳婼的解法才搞定的。开始想着把height和parent放到结构体中去&#xff0c;很繁琐最后还搞不定…… #include <cstdio> #include <algorithm> #include <vector>struct node{int key;node* left nullptr;node* right nullptr; };int N, t, pi…