高通MSM8953 LK阶段配置使用I2C8[通俗易懂]

高通MSM8953 LK阶段配置使用I2C8[通俗易懂]项目场景: 因为项目需要,需要在高通MSM8953平台的LK阶段使用I2C8设备。但是MSM8953平台LK阶段并没有配置好I2C8接口,因此调试I2C8成为当务之急。本文只介绍在LK阶段配置使用I2C5的方法。调试需要:1、文档:BAMLow-SpeedPeripherals(BLSP)UserGuide查看文档,有I2C介绍如下:I2c3对应的物理地址为0x78B7000,中断IRQ:97,时钟信号clk:clk_gcc_blsp1_qup3_i2c_apps_clk

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

项目场景:

	因为项目需要,需要在高通MSM8953平台的LK阶段使用I2C8设备。但是MSM8953平台LK阶段并没有配置好I2C8接口,因此调试I2C8成为当务之急。本文只介绍在LK阶段配置使用I2C5的方法。

调试需要:

1、文档:BAM Low-Speed Peripherals (BLSP) User Guide
查看文档,有I2C介绍如下:
在这里插入图片描述
I2c3对应的物理地址为0x78B7000 , 中断IRQ:97 ,时钟信号 clk :clk_gcc_blsp1_qup3_i2c_apps_clk ,
I2c3对应的物理地址为0x7AF8000 , 中断IRQ:302,时钟信号 clk :clk_gcc_blsp2_qup4_i2c_apps_clk
查看产品配置表有:
I2C3:gpio10&gpio11;i2c8:gpio98&gpio99;

I2C Description :
		1、 arg: BLSP ID can be BLSP_ID_1 or BLSP_ID_2
		2、 arg: QUP ID can be QUP_ID_0:QUP_ID_5
		3、 arg: I2C CLK. should be 100KHZ, or 400KHz
		4、 arg: Source clock, should be set @ 19.2MHz

解决方案:

1、Initialize the I2C bus.

//mipi_dsi_i2c.c
#define I2C_CLK_FREQ 100000
#define I2C_SRC_CLK_FREQ 19200000

int mipi_dsi_i2c_device_init(uint8_t blsp_id, uint8_t qup_id)
{ 
   
	if(BLSP_ID_2 == blsp_id) { 
   
		i2c8_dev = qup_blsp_i2c_init(blsp_id, qup_id,
					I2C_CLK_FREQ, I2C_SRC_CLK_FREQ);
		if(!i2c8_dev) { 
   
			dprintf(CRITICAL, "mipi_dsi_i2c_device_init() failed\n");
			return ERR_NOT_VALID;
		}
	}
	else
	{ 
   
		i2c_dev = qup_blsp_i2c_init(blsp_id, qup_id,
					I2C_CLK_FREQ, I2C_SRC_CLK_FREQ);
		if(!i2c_dev) { 
   
			dprintf(CRITICAL, "mipi_dsi_i2c_device_init() failed\n");
			return ERR_NOT_VALID;
		}

	}
	return NO_ERROR;
}
//i2c_qup.c
#include <blsp_qup.h>
#include <platform.h>

static struct qup_i2c_dev *dev_addr = NULL;
static struct qup_i2c_dev *dev8_addr = NULL;

struct qup_i2c_dev *qup_blsp_i2c_init(uint8_t blsp_id, uint8_t qup_id,
									  uint32_t clk_freq, uint32_t src_clk_freq)
{ 
   
	struct qup_i2c_dev *dev;

	if(BLSP_ID_2 == blsp_id)
	{ 
   
		if (dev8_addr != NULL) { 
   
			return dev8_addr;
		}
	}
	else 
	{ 
   
		if (dev_addr != NULL) { 
   
			return dev_addr;
		}
	}
	
	dev = malloc(sizeof(struct qup_i2c_dev));
	if (!dev) { 
   
		return NULL;
	}
	dev = memset(dev, 0, sizeof(struct qup_i2c_dev));

	/* Platform uses BLSP */
	dev->qup_irq = BLSP_QUP_IRQ(blsp_id, qup_id);
	dev->qup_base = BLSP_QUP_BASE(blsp_id, qup_id);

	/* This must be done for qup_i2c_interrupt to work. */
	if(BLSP_ID_2 == blsp_id)
		dev8_addr = dev;
	else
		dev_addr = dev;

	/* Initialize the GPIO for BLSP i2c */
	gpio_config_blsp_i2c(blsp_id, qup_id);

	clock_config_blsp_i2c(blsp_id, qup_id);

	qup_i2c_sec_init(dev, clk_freq, src_clk_freq);

	return dev;
}

添加I2C8操作函数

// i2c_qup.c
int mipi_dsi_i2c8_read_bytes(uint8_t addr, uint8_t *reg, uint8_t *buf, uint8_t len)
{ 
   
		
	if (!buf)
		return ERR_INVALID_ARGS;

	if(!i2c8_dev)
		return ERR_NOT_VALID;

	struct i2c_msg rd_buf[] = { 
   
		{ 
   addr, I2C_M_WR, 2, reg},
		{ 
   addr, I2C_M_RD, len, buf}
	};

	int err = qup_i2c_xfer(i2c8_dev, rd_buf, 2);
	if (err < 0) { 
   
		dprintf(CRITICAL, "Read reg %x failed\n", (int)reg[0]);
		return err;
	}

	return NO_ERROR;
}

int mipi_dsi_i2c8_write_bytes(uint8_t addr, uint8_t *reg, uint32_t len)
{ 
   
	if (!i2c8_dev)
		return ERR_NOT_VALID;
	
	struct i2c_msg msg_buf[] = { 
   
		{ 
   addr, I2C_M_WR, len, reg},
	};

	int err = qup_i2c_xfer(i2c8_dev, msg_buf, 1);
	if (err < 0) { 
   
		dprintf(CRITICAL, "Write reg %x failed\n", (int)reg[0]);
		return err;
	}
	return NO_ERROR;
}


int mipi_dsi_i2c8_read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
{ 
   
	if (!buf)
		return ERR_INVALID_ARGS;

	if(!i2c8_dev)
		return ERR_NOT_VALID;

	struct i2c_msg rd_buf[] = { 
   
		{ 
   addr, I2C_M_WR, 1, &reg},
		{ 
   addr, I2C_M_RD, len, buf}
	};

	int err = qup_i2c_xfer(i2c8_dev, rd_buf, 2);
	if (err < 0) { 
   
		dprintf(CRITICAL, "Read reg %x failed\n", reg);
		return err;
	}

	return NO_ERROR;
}

int mipi_dsi_i2c8_read_byte(uint8_t addr, uint8_t reg, uint8_t *buf)
{ 
   
	if (!buf)
		return ERR_INVALID_ARGS;

	return mipi_dsi_i2c8_read(addr, reg, buf, 1);
}

int mipi_dsi_i2c8_write_byte(uint8_t addr, uint8_t reg, uint8_t val)
{ 
   
	if (!i2c8_dev)
		return ERR_NOT_VALID;

	unsigned char buf[2] = { 
   reg, val};
	struct i2c_msg msg_buf[] = { 
   
		{ 
   addr, I2C_M_WR, 2, buf},
	};

	int err = qup_i2c_xfer(i2c8_dev, msg_buf, 1);
	if (err < 0) { 
   
		dprintf(CRITICAL, "Write reg %x failed\n", reg);
		return err;
	}
	return NO_ERROR;
}

声明函数

// mipi_dsi_i2c.h

int mipi_dsi_i2c8_read_bytes(uint8_t addr, uint8_t *reg, uint8_t *buf, uint8_t len);
int mipi_dsi_i2c8_write_bytes(uint8_t addr, uint8_t *reg, uint32_t len);
int mipi_dsi_i2c8_read_byte(uint8_t addr, uint8_t reg, uint8_t *buf);
int mipi_dsi_i2c8_write_byte(uint8_t addr, uint8_t reg, uint8_t val);
int mipi_dsi_i2c8_read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);

查看文档,可以得知IRQ计算公式为:

#define BLSP_QUP_IRQ(blsp_id, qup_id) (GIC_SPI_START + 95 + (blsp_id-1)*204 + qup_id)

物理地址计算公式为:

#define BLSP_QUP_BASE(blsp_id, qup_id) (PERIPH_SS_BASE + ((blsp_id) - 1) * 0x240000 \ + 0xB5000 + 0x1000 * (qup_id))

2、 Configure the GPIO.

// bootloader/lk/platform/msm8953/gpio.c
#define GPIO_BLSP1_ACTIVE_1 10
#define GPIO_BLSP1_ACTIVE_2 11

#define GPIO_BLSP2_ACTIVE_1 98
#define GPIO_BLSP2_ACTIVE_2 99

void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
{ 
   
	if(blsp_id == BLSP_ID_1) { 
   
		switch (qup_id) { 
   
			case QUP_ID_2:
				/* configure I2C SDA gpio */
				gpio_tlmm_config(GPIO_BLSP1_ACTIVE_1, 2, GPIO_OUTPUT,
					GPIO_NO_PULL, GPIO_6MA, GPIO_ENABLE);

				/* configure I2C SCL gpio */
				gpio_tlmm_config(GPIO_BLSP1_ACTIVE_2, 2, GPIO_OUTPUT,
					GPIO_NO_PULL, GPIO_6MA, GPIO_ENABLE);

			break;
			default:
				dprintf(CRITICAL, "Incorrect QUP id %d\n", qup_id);
				ASSERT(0);
		};
	}
	else if(blsp_id == BLSP_ID_2) { 
   
		switch (qup_id) { 
   
			case QUP_ID_3:
				/* configure I2C SDA gpio */
				gpio_tlmm_config(GPIO_BLSP2_ACTIVE_1, 1, GPIO_OUTPUT,
					GPIO_PULL_UP, GPIO_6MA, GPIO_ENABLE);

				/* configure I2C SCL gpio */
				gpio_tlmm_config(GPIO_BLSP2_ACTIVE_2, 1, GPIO_OUTPUT,
					GPIO_PULL_UP, GPIO_6MA, GPIO_ENABLE);
			break;
			default:
				dprintf(CRITICAL, "Incorrect QUP id %d\n", qup_id);
				ASSERT(0);
		};
	}	
	else { 
   
		dprintf(CRITICAL, "Incorrect BLSP id %d\n",blsp_id);
		ASSERT(0);
	}
}

3、Register a clock.

// bootable/bootloader/lk/platform/msm8953/acpuclock.c.
void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
{ 
   
	uint8_t ret = 0;
	char clk_name[64];

	struct clk *qup_clk;

	if((blsp_id != BLSP_ID_1 && blsp_id != BLSP_ID_2)) { 
   
		dprintf(CRITICAL, "Incorrect BLSP-%d or QUP-%d configuration\n",
			blsp_id, qup_id);
		ASSERT(0);
	}
	if(blsp_id == BLSP_ID_1){ 
   

		if (qup_id == QUP_ID_2) { 
   
			snprintf(clk_name, sizeof(clk_name), "blsp1_qup3_ahb_iface_clk");
		}
		else if (qup_id == QUP_ID_3) { 
   
			snprintf(clk_name, sizeof(clk_name), "blsp1_qup4_ahb_iface_clk");
		}
	}
	
	if(blsp_id == BLSP_ID_2){ 
   
		if (qup_id == QUP_ID_3) { 
   
			snprintf(clk_name, sizeof(clk_name), "blsp2_qup4_ahb_iface_clk");
		}
	}

	ret = clk_get_set_enable(clk_name, 0 , 1);
	if (ret) { 
   
		dprintf(CRITICAL, "Failed to enable %s clock\n", clk_name);
		return;
	}

	if(blsp_id == BLSP_ID_1){ 
   
		if (qup_id == QUP_ID_2) { 
   
			snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup3_i2c_apps_clk");
		}
		else if (qup_id == QUP_ID_3) { 
   
			snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup4_i2c_apps_clk");
		}
	}
	if(blsp_id == BLSP_ID_2){ 
   
		if (qup_id == QUP_ID_3) { 
   
			snprintf(clk_name, sizeof(clk_name), "gcc_blsp2_qup4_i2c_apps_clk");
		}
	}
	qup_clk = clk_get(clk_name);
	if (!qup_clk) { 
   
		dprintf(CRITICAL, "Failed to get %s\n", clk_name);
		return;
	}

	ret = clk_enable(qup_clk);
	if (ret) { 
   
		dprintf(CRITICAL, "Failed to enable %s\n", clk_name);
		return;
	}
}
// bootable/bootloader/lk/platform/msm8953/msm8953-clock.c.

static struct vote_clk gcc_blsp2_ahb_clk = { 
   
	.cbcr_reg     = (uint32_t *) BLSP2_AHB_CBCR,
	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
	.en_mask      = BIT(20),

	.c = { 
   
		.dbg_name = "gcc_blsp2_ahb_clk",
		.ops      = &clk_ops_vote,
	},
};

static struct clk_freq_tbl ftbl_gcc_blsp1_qup2_i2c_apps_clk_src[] = { 
   
	F(      96000,    cxo,  10,   1,  2),
	F(    4800000,    cxo,   4,   0,  0),
	F(    9600000,    cxo,   2,   0,  0),
	F(   16000000,  gpll0,  10,   1,  5),
	F(   19200000,  gpll0,   1,   0,  0),
	F(   25000000,  gpll0,  16,   1,  2),
	F(   50000000,  gpll0,  16,   0,  0),
	F_END
};

static struct rcg_clk gcc_blsp1_qup2_i2c_apps_clk_src = { 
   
	.cmd_reg      = (uint32_t *) GCC_BLSP1_QUP2_CMD_RCGR,
	.cfg_reg      = (uint32_t *) GCC_BLSP1_QUP2_CFG_RCGR,
	.set_rate     = clock_lib2_rcg_set_rate_hid,
	.freq_tbl     = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src,
	.current_freq = &rcg_dummy_freq,

	.c = { 
   
		.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk_src",
		.ops      = &clk_ops_rcg,
	},
};

static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = { 
   
	.cbcr_reg = (uint32_t *) GCC_BLSP1_QUP2_APPS_CBCR,
	.parent   = &gcc_blsp1_qup2_i2c_apps_clk_src.c,

	.c = { 
   
		.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
		.ops      = &clk_ops_branch,
	},
};

static struct clk_freq_tbl ftbl_gcc_blsp1_qup3_i2c_apps_clk_src[] = { 
   
	F(      96000,    cxo,  10,   1,  2),
	F(    4800000,    cxo,   4,   0,  0),
	F(    9600000,    cxo,   2,   0,  0),
	F(   16000000,  gpll0,  10,   1,  5),
	F(   19200000,  gpll0,   1,   0,  0),
	F(   25000000,  gpll0,  16,   1,  2),
	F(   50000000,  gpll0,  16,   0,  0),
	F_END
};

#if 0
static struct clk_freq_tbl ftbl_gcc_blsp2_qup4_i2c_apps_clk_src[] = { 
   
	F(      96000,    cxo,  10,   1,  2),
	F(    4800000,    cxo,   4,   0,  0),
	F(    9600000,    cxo,   2,   0,  0),
	F(   16000000,  gpll0,  10,   1,  5),
	F(   19200000,  gpll0,   1,   0,  0),
	F(   25000000,  gpll0,  16,   1,  2),
	F(   50000000,  gpll0,  16,   0,  0),
	F_END
};
#endif

static struct rcg_clk gcc_blsp1_qup3_i2c_apps_clk_src = { 
   
	.cmd_reg      = (uint32_t *) GCC_BLSP1_QUP3_CMD_RCGR,
	.cfg_reg      = (uint32_t *) GCC_BLSP1_QUP3_CFG_RCGR,
	.set_rate     = clock_lib2_rcg_set_rate_hid,
	.freq_tbl     = ftbl_gcc_blsp1_qup3_i2c_apps_clk_src,
	.current_freq = &rcg_dummy_freq,

	.c = { 
   
		.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk_src",
		.ops      = &clk_ops_rcg,
	},
};

static struct rcg_clk gcc_blsp2_qup4_i2c_apps_clk_src = { 
   
	.cmd_reg      = (uint32_t *) GCC_BLSP2_QUP4_CMD_RCGR,
	.cfg_reg      = (uint32_t *) GCC_BLSP2_QUP4_CFG_RCGR,
	.set_rate     = clock_lib2_rcg_set_rate_hid,
// .freq_tbl = ftbl_gcc_blsp2_qup4_i2c_apps_clk_src,
	.freq_tbl	  = ftbl_gcc_blsp1_qup3_i2c_apps_clk_src,
	.current_freq = &rcg_dummy_freq,

	.c = { 
   
		.dbg_name = "gcc_blsp2_qup4_i2c_apps_clk_src",
		.ops      = &clk_ops_rcg,
	},
};

static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = { 
   
	.cbcr_reg = (uint32_t *) GCC_BLSP1_QUP3_APPS_CBCR,
	.parent   = &gcc_blsp1_qup3_i2c_apps_clk_src.c,

	.c = { 
   
		.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
		.ops      = &clk_ops_branch,
	},
};

static struct branch_clk gcc_blsp2_qup4_i2c_apps_clk = { 
   
	.cbcr_reg = (uint32_t *) GCC_BLSP2_QUP4_APPS_CBCR,
	.parent   = &gcc_blsp2_qup4_i2c_apps_clk_src.c,

	.c = { 
   
		.dbg_name = "gcc_blsp2_qup4_i2c_apps_clk",
		.ops      = &clk_ops_branch,
	},
};


static struct clk_freq_tbl ftbl_mdss_esc1_1_clk[] = { 
   
	F_MM(19200000,    cxo,   1,   0,   0),
	F_END
};

static struct rcg_clk dsi_esc1_clk_src = { 
   
	.cmd_reg  = (uint32_t *) DSI_ESC1_CMD_RCGR,
	.cfg_reg  = (uint32_t *) DSI_ESC1_CFG_RCGR,
	.set_rate = clock_lib2_rcg_set_rate_hid,
	.freq_tbl = ftbl_mdss_esc1_1_clk,

	.c        = { 
   
		.dbg_name = "dsi_esc1_clk_src",
		.ops      = &clk_ops_rcg,
	},
};

static struct branch_clk mdss_esc1_clk = { 
   
	.cbcr_reg    = (uint32_t *) DSI_ESC1_CBCR,
	.parent      = &dsi_esc1_clk_src.c,
	.has_sibling = 0,

	.c           = { 
   
		.dbg_name = "mdss_esc1_clk",
		.ops      = &clk_ops_branch,
	},
};

static struct clk_lookup msm_clocks_8953[] =
{ 
   
...
/*add start by Yubel for blsp 20200730 */
	/* BLSP CLOCKS */
	CLK_LOOKUP("blsp1_qup2_ahb_iface_clk", gcc_blsp1_ahb_clk.c),
	CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk_src",
		gcc_blsp1_qup2_i2c_apps_clk_src.c),
	CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk",
		gcc_blsp1_qup2_i2c_apps_clk.c),

	CLK_LOOKUP("blsp1_qup3_ahb_iface_clk", gcc_blsp1_ahb_clk.c),
	CLK_LOOKUP("gcc_blsp1_qup3_i2c_apps_clk_src",
		gcc_blsp1_qup3_i2c_apps_clk_src.c),
	CLK_LOOKUP("gcc_blsp1_qup3_i2c_apps_clk",
		gcc_blsp1_qup3_i2c_apps_clk.c),

	CLK_LOOKUP("blsp2_qup4_ahb_iface_clk", gcc_blsp2_ahb_clk.c),
	CLK_LOOKUP("gcc_blsp2_qup4_i2c_apps_clk_src",
		gcc_blsp2_qup4_i2c_apps_clk_src.c),
	CLK_LOOKUP("gcc_blsp2_qup4_i2c_apps_clk",
		gcc_blsp2_qup4_i2c_apps_clk.c),

/*add end by Yubel 20200730 */
...	
};

通过kernel中配置I2C的代码可知

#define GCC_BLSP1_QUP3_APPS_CBCR (CLK_CTL_BASE + 0x04020)
#define GCC_BLSP1_QUP3_CFG_RCGR (CLK_CTL_BASE + 0x04004)
#define GCC_BLSP1_QUP3_CMD_RCGR (CLK_CTL_BASE + 0x04000)
	
#define GCC_BLSP1_QUP2_APPS_CBCR (CLK_CTL_BASE + 0x03010)
#define GCC_BLSP1_QUP2_CFG_RCGR (CLK_CTL_BASE + 0x03004)
#define GCC_BLSP1_QUP2_CMD_RCGR (CLK_CTL_BASE + 0x03000)

#define BLSP2_AHB_CBCR (CLK_CTL_BASE + 0x0B008)

#define GCC_BLSP2_QUP4_APPS_CBCR (CLK_CTL_BASE + 0x18020)
#define GCC_BLSP2_QUP4_CFG_RCGR (CLK_CTL_BASE + 0x18004)
#define GCC_BLSP2_QUP4_CMD_RCGR (CLK_CTL_BASE + 0x18000)

测试用例

// bootable/bootloader/lk/app/tests/my_i2c_test.c.
#include <ctype.h>
#include <debug.h>
#include <stdlib.h>
#include <printf.h>
#include <list.h>
#include <string.h>
#include <arch/ops.h>
#include <platform.h>
#include <platform/debug.h>
#include <kernel/thread.h>
#include <kernel/timer.h>
#ifdef WITH_LIB_CONSOLE
#include <lib/console.h>
static int cmd_i2c_test(int argc, const cmd_args *argv);
STATIC_COMMAND_START
 { 
    "i2c_test", "i2c test cmd", &cmd_i2c_test },
STATIC_COMMAND_END(my_i2c_test);
static int cmd_i2c_test(int argc, const cmd_args *argv)
{ 
   
 printf("Entering i2c_test\n");
 return 0;
}
#endif

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/180313.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java课程设计_java课设「建议收藏」

    Java课程设计_java课设「建议收藏」1.代码截图:2.设计思路建立GUI界面,系统产生一个随机数(对用户不可见),然后用户输入猜测数,系统根据用户每次输入的数据给出评语(偏大,偏小,猜测成功)。当用户最终猜测成功后,就把当次的随机数和猜测次数放到文件夹内。3.遇到的问题:(1).Guess里面每次产生的随机数m和最终猜测次数n一直不知道怎么传到sava里并保存输出到文件。(2).怎么在生成的guessgame文件里追加内容,而不是每…

    2022年7月12日
    18
  • C++线程池实现_java线程池状态

    C++线程池实现_java线程池状态在计算机程序中,线程是一种很重要的资源,使用的恰当可以极大的提高程序的效率,也就是多线程的使用,但是多线程会让应用程序变得异常复杂,会占用大量的系统资源。就像QQ表情一样,每一个QQ表情的闪动都需要构建一个线程,如果用户使用了大量的表情(GIF),将会有多少个线程在运行,系统的性能将大大减少,甚至导致死机。在这种情况下,多线程变得不太合适了,那么什么机制适用于这种情况下呢,这就是线程池。通常情

    2022年9月25日
    1
  • 仙剑—相爱

    仙剑—相爱

    2022年2月4日
    46
  • mysql 截取字符串部分值_mysql截取字符串取值

    mysql 截取字符串部分值_mysql截取字符串取值使用mysql过程中根据实际业务的开发需求和表的设计有时候我们需要在sql中根据某个字符串截取并且取值:demo如下:ifnull(max(SUBSTRING_INDEX(c.check_score,’,’,-1)),’-‘)swjdf//按照,截取check_score这个字段的值,-1取的是倒数第一位即最后一位SUBSTRING_INDEX函数语法:SUBSTRING_INDEX(str…

    2022年6月11日
    137
  • [渝粤教育] 徐州工业职业技术学院 橡胶原材料 参考 资料「建议收藏」

    [渝粤教育] 徐州工业职业技术学院 橡胶原材料 参考 资料「建议收藏」教育-橡胶原材料-章节资料考试资料-徐州工业职业技术学院【】课程认知随堂测验1、【多选题】下列制品可采用橡胶材料制作的是。A、轮胎B、鞋子底C、输送带D、婴儿奶嘴参考资料【】2、【多选题】硫化体系主要包括。A、硫化剂B、促进剂C、活性剂D、防焦剂参考资料【】3、【判断题】橡胶是一种材料,它在大的形变下能迅速而有力恢复其形变,能够被改性(硫化)。A、正确B、错误参考资料【】4、【判断题】生胶是一种高弹性高聚物材料,是制造橡胶制品的基础材料,一

    2022年10月2日
    3
  • idea注释的快捷键三种方式

    idea注释的快捷键三种方式1、第一种单行注释(ctrl+/)光标处于当前需要写注释的这一行,在这行任何位置都可以,可以调整的,ctrl+/即可实现单行注释,如图,当想取消时,也可以使用ctrl+/取消行注释2、第二种,多行注释(ctrl+shift+/)多行注释,先选中需要注释的这一行,使用ctrl+shift+/即可实现多行注释,当然,想取消的话,也可以使用ctrl+shift+/3、方法或者类说明注释,自动带参数和返回值在需要注释的位置,输入/**,然后按一下enter即可实现,自动根据参数和返回值生成注释,

    2022年9月29日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号