RK3568驱动指南|第十四篇 单总线-第165章DS18B20驱动使用ioctl读取分辨率

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。


【公众号】迅为电子

【粉丝群】824412014(加群获取驱动文档+例程)

【视频观看】嵌入式学习之Linux驱动(第十四篇 单总线_全新升级)_基于RK3568

【购买链接】迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板


第165章DS18B20驱动使用ioctl读取分辨率

在上个章节中成功在驱动中添加了ioctl相关代码,通过ioctl对DS18B20采集到的温度分辨率进行设置。而在本章节将继续完善驱动程序,对DS18B20采集到的温度分辨率进行读取,然后编写相应的应用程序进行分辨率读取测试。

165.1 ioctl读取分辨率驱动代码编写

本实验对应的网盘路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\100_ds18b20_07\01_module

相较于上一章节的驱动代码,添加了ioctl查看分辨率相关的函数,除此之外完成了查看温度分辨率函数read_resolution(),编写完成的ds18b20.c代码如下所示:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h> // 添加此头文件
#include <linux/delay.h>
#include <linux/uaccess.h>

#define SET_RESOLUTION _IOW('A', 0, int)
#define READ_RESOLUTION _IOR('A', 1, int)

#define SET_RESOLUTION_9 9
#define SET_RESOLUTION_10 10
#define SET_RESOLUTION_11 11
#define SET_RESOLUTION_12 12

struct ds18b20_data
{
    dev_t dev_num;
    struct cdev ds18b20_cdev;
    struct class *ds18b20_class;
    struct device *ds18b20_device;
    struct gpio_desc *ds18b20_gpio;
};

struct ds18b20_data *ds18b20;

void ds18b20_reset(void)
{
    // 设置 GPIO 方向为输出,输出低电平
    gpiod_direction_output(ds18b20->ds18b20_gpio, 1);
    gpiod_set_value(ds18b20->ds18b20_gpio, 0);
    udelay(700); // 延迟 700 微秒

    // 设置 GPIO 输出高电平,并将 GPIO 方向设置为输入
    gpiod_set_value(ds18b20->ds18b20_gpio, 1);
    gpiod_direction_input(ds18b20->ds18b20_gpio);

    // 等待直到 GPIO 输入为低电平
    while (gpiod_get_value(ds18b20->ds18b20_gpio))
        ;

    // 等待直到 GPIO 输入为高电平
    while (!gpiod_get_value(ds18b20->ds18b20_gpio))
        ;
    udelay(480); // 延迟 480 微秒
}

/**
 * 向 DS18B20 写入单个位(bit)
 * @param bit 要写入的位(bit),0 或 1
 */
void ds18b20_writebit(unsigned char bit) {
    // 将 GPIO 方向设置为输出
    gpiod_direction_output(ds18b20->ds18b20_gpio, 1);

    // 将 GPIO 输出设置为指定的位(bit)
    gpiod_set_value(ds18b20->ds18b20_gpio, 0);

    // 若 bit 为 1,则延时 10 微秒
    if (bit){
        udelay(10);  
        // 将 GPIO 方向设置为输出
    	gpiod_direction_output(ds18b20->ds18b20_gpio, 1);
    }
       

    // 延时 65 微秒
    udelay(65);

    // 将 GPIO 方向设置为输出
    gpiod_direction_output(ds18b20->ds18b20_gpio, 1);

    // 延时 2 微秒
    udelay(2);
}

/**
 * 向 DS18B20 写入一个字节(byte)数据
 * @param data 要写入的字节数据
 */
void ds18b20_writebyte(int data) {
    int i;

    for (i = 0; i < 8; i++) {
        // 逐位写入数据
        ds18b20_writebit(data & 0x01);
        data = data >> 1;
    }
}

/**
 * 从 DS18B20 读取单个位(bit)
 * @return 读取到的位(bit),0 或 1
 */
unsigned char ds18b20_readbit(void) {
    unsigned char bit;        
    gpiod_direction_output(ds18b20->ds18b20_gpio, 1);// 将 GPIO 方向设置为输出        
    gpiod_set_value(ds18b20->ds18b20_gpio, 0);// 将 GPIO 输出设置为低电平        
    udelay(2);// 延时 2 微秒        
    gpiod_direction_input(ds18b20->ds18b20_gpio);// 将 GPIO 方向设置为输入   
    udelay(10);// 延时 10 微秒       
    bit = gpiod_get_value(ds18b20->ds18b20_gpio);// 读取 GPIO 的值作为位(bit)       
    udelay(60);// 延时 60 微秒
    
    return bit;
}

/**
 * 从 DS18B20 读取一个字节(byte)数据
 * @return 读取到的字节数据
 */
int ds18b20_readbyte(void) {
    int data = 0;
    int i;
    
    for (i = 0; i < 8; i++) {
        // 读取单个位(bit)并根据位的位置进行左移操作
        data |= ds18b20_readbit() << i;
    }
    
    return data;
}

/**
 * 从 DS18B20 读取温度值
 * @return 读取到的温度值
 */
int ds18b20_readtemp(void) {
    int temp_l, temp_h, temp;   
    
    ds18b20_reset();// 复位 DS18B20    
    ds18b20_writebyte(0xCC);// 发送写入字节命令 0xCC(跳过 ROM)   
    ds18b20_writebyte(0x44);// 发送写入字节命令 0x44(启动温度转换)    
    mdelay(750);// 延时 750 微秒,等待温度转换完成
    
    ds18b20_reset();// 复位 DS18B20        
    ds18b20_writebyte(0xCC);// 发送写入字节命令 0xCC(跳过 ROM)       
    ds18b20_writebyte(0xBE);// 发送写入字节命令 0xBE(读取温度值)        
    temp_l = ds18b20_readbyte();// 读取温度低位字节        
    temp_h = ds18b20_readbyte();// 读取温度高位字节        
    temp_h = temp_h << 8;// 将温度高位字节左移 8 位
    temp = temp_h | temp_l;// 组合温度值
    
    return temp;
} 

/**
 * 设置 DS18B20 温度传感器的分辨率
 * @param args 分辨率参数
 */
void set_resolution(int args) {
    ds18b20_reset();  // 复位 DS18B20 温度传感器
    ds18b20_writebyte(0xCC);  // 发送跳过 ROM 命令
    ds18b20_writebyte(0x4E);  // 发送写配置寄存器命令
    ds18b20_writebyte(60);  // 发送配置字节 1,设置温度上限阈值
    ds18b20_writebyte(10);  // 发送配置字节 2,设置温度下限阈值

    switch (args) {
        case SET_RESOLUTION_9:  // 设置分辨率为 9 位
            ds18b20_writebyte(0x1F);  // 发送配置字节 3,设置分辨率为 9 位
            break;
        case SET_RESOLUTION_10:  // 设置分辨率为 10 位
            ds18b20_writebyte(0x3F);  // 发送配置字节 3,设置分辨率为 10 位
            break;
        case SET_RESOLUTION_11:  // 设置分辨率为 11 位
            ds18b20_writebyte(0x5F);  // 发送配置字节 3,设置分辨率为 11 位
            break;
        case SET_RESOLUTION_12:  // 设置分辨率为 12 位
            ds18b20_writebyte(0x7F);  // 发送配置字节 3,设置分辨率为 12 位
            break;
        default:
            break;
    }
}

/**
 * 检查参数的有效性
 * @param args 参数
 * @return 返回执行结果,成功返回 0,失败返回 -1
 */
int check_args(int args) {
    int ret = -1;  // 返回值,默认为失败

    ds18b20_reset();  // 复位传感器
    ds18b20_writebyte(0xCC);  // 发送指令字节 0xCC
    ds18b20_writebyte(0xBE);  // 发送指令字节 0xBE
    ds18b20_readbyte();  // 读取一个字节
    ds18b20_readbyte();  // 读取一个字节
    ds18b20_readbyte();  // 读取一个字节
    ds18b20_readbyte();  // 读取一个字节

    switch (args) {
        case SET_RESOLUTION_9:
            if (ds18b20_readbyte() == 0x1F) {  // 读取一个字节并与 0x1F 进行比较
                ret = 0;  // 设置返回值为成功
            }
            break;
        case SET_RESOLUTION_10:
            if (ds18b20_readbyte() == 0x3F) {  // 读取一个字节并与 0x3F 进行比较
                ret = 0;  // 设置返回值为成功
            }
            break;
        case SET_RESOLUTION_11:
            if (ds18b20_readbyte() == 0x5F) {  // 读取一个字节并与 0x5F 进行比较
                ret = 0;  // 设置返回值为成功
            }
            break;
        case SET_RESOLUTION_12:
            if (ds18b20_readbyte() == 0x7F) {  // 读取一个字节并与 0x7F 进行比较
                ret = 0;  // 设置返回值为成功
            }
            break;
        default:
            break;
    }

    return ret;  // 返回结果
}


/**
 * 读取分辨率。
 *
 * @return 分辨率值
 */
int read_resolution(void) {
    int ret;

    // 复位传感器
    ds18b20_reset();

    // 发送指令字节0xCC,跳过ROM操作,直接与单个设备通信
    ds18b20_writebyte(0xCC);

    // 发送指令字节0xBE,读取当前设备的配置寄存器
    ds18b20_writebyte(0xBE);

    // 读取4个字节的数据,但实际上只有最后一个字节是分辨率信息
    ds18b20_readbyte();
    ds18b20_readbyte();
    ds18b20_readbyte();
    ds18b20_readbyte();

    // 读取最后一个字节,即分辨率信息
    ret = ds18b20_readbyte();

    // 返回分辨率值
    return ret;
}


int ds18b20_open(struct inode *inode, struct file *file)
{
    return 0;
}

ssize_t ds18b20_read(struct file *file, char __user *buf, size_t size, loff_t *offs) {
    int ds18b20_temp;    
    ds18b20_temp = ds18b20_readtemp();// 从 DS18B20 读取温度值    
    // 将温度值复制到用户空间缓冲区
    if (copy_to_user(buf, &ds18b20_temp, sizeof(ds18b20_temp))) {
        return -1; // 复制失败,返回错误代码
    }
    
    return 0; // 成功读取并复制温度值
}

int ds18b20_release(struct inode *inode, struct file *file)
{
    return 0;
}

/**
 * DS18B20 温度传感器的 ioctl 函数
 * @param file 文件指针
 * @param cmd 命令
 * @param args 参数
 * @return 返回执行结果,成功返回 0,失败返回 -1
 */
long ds18b20_ioctl(struct file *file, unsigned int cmd, unsigned long args) {
    int resolution;
    if (cmd == SET_RESOLUTION) {  // 判断命令是否为设置分辨率
        if (args >= SET_RESOLUTION_9 && args <= SET_RESOLUTION_12) {  // 判断参数是否在有效的分辨率范围内
            set_resolution(args);  // 调用设置分辨率的函数
            return 0;  // 返回成功
        }
    }
    else if (cmd == READ_RESOLUTION) {
        // 读取分辨率
        resolution = read_resolution();
        // 将分辨率的值复制给用户空间的args
        if (copy_to_user((int *)args, &resolution, sizeof(resolution))) {
            // 复制失败,返回-1表示失败
            return -1;
        }
    }
    // 如果不匹配 SET_RESOLUTION 或者 args 不在有效范围内,不执行任何操作
    return -1;  // 返回失败
}

struct file_operations ds18b20_fops = {
    .open = ds18b20_open,
    .read = ds18b20_read,
    .release = ds18b20_release,
    .unlocked_ioctl = ds18b20_ioctl,
    .owner = THIS_MODULE,
};

int ds18b20_probe(struct platform_device *dev)
{
    int ret;
    printk("This is probe \n");

    // 分配内存给ds18b20_data结构体
    ds18b20 = kzalloc(sizeof(*ds18b20), GFP_KERNEL);
    if (ds18b20 == NULL)
    {
        printk("kzalloc error\n");
        ret = -ENOMEM;
        goto error_0;
    }

    // 分配字符设备号
    ret = alloc_chrdev_region(&ds18b20->dev_num, 0, 1, "myds18b20");
    if (ret < 0)
    {
        printk("alloc_chrdev_region error\n");
        ret = -EAGAIN;
        goto error_1;
    }

    // 初始化字符设备
    cdev_init(&ds18b20->ds18b20_cdev, &ds18b20_fops);
    ds18b20->ds18b20_cdev.owner = THIS_MODULE;
    cdev_add(&ds18b20->ds18b20_cdev, ds18b20->dev_num, 1);

    // 创建设备类
    ds18b20->ds18b20_class = class_create(THIS_MODULE, "sensors");
    if (IS_ERR(ds18b20->ds18b20_class))
    {
        printk("class_create error\n");
        ret = PTR_ERR(ds18b20->ds18b20_class);
        goto error_2;
    }

    // 创建设备
    ds18b20->ds18b20_device = device_create(ds18b20->ds18b20_class, NULL, ds18b20->dev_num, NULL, "ds18b20");
    if (IS_ERR(ds18b20->ds18b20_device))
    {
        printk("device_create error\n");
        ret = PTR_ERR(ds18b20->ds18b20_device);
        goto error_3;
    }

    // 获取GPIO描述符
    ds18b20->ds18b20_gpio = gpiod_get_optional(&dev->dev, "ds18b20", 0);
    if (ds18b20->ds18b20_gpio == NULL)
    {
        ret = -EBUSY;
        goto error_4;
    }

    // 设置GPIO方向为输出
    gpiod_direction_output(ds18b20->ds18b20_gpio, 1);

    return 0;

    error_4:
    device_destroy(ds18b20->ds18b20_class, ds18b20->dev_num);

    error_3:
    class_destroy(ds18b20->ds18b20_class);

    error_2:
    cdev_del(&ds18b20->ds18b20_cdev);
    unregister_chrdev_region(ds18b20->dev_num, 1);

    error_1:
    kfree(ds18b20);

    error_0:
    return ret;
}

const struct of_device_id ds18b20_match_table[] = {
    {.compatible = "ds18b20"},
    {},
};

struct platform_driver ds18b20_driver = {
    .driver = {
        .owner = THIS_MODULE,
        .name = "ds18b20",
        .of_match_table = ds18b20_match_table,
    },
    .probe = ds18b20_probe,
};

static int __init ds18b20_init(void)
{
    int ret;

    // 注册平台驱动
    ret = platform_driver_register(&ds18b20_driver);
    if (ret < 0)
    {
        printk("platform_driver_register error\n");
        return -1;
    }

    return 0;
}

static void __exit ds18b20_exit(void)
{
    // 释放资源
    gpiod_put(ds18b20->ds18b20_gpio);
    device_destroy(ds18b20->ds18b20_class, ds18b20->dev_num);
    class_destroy(ds18b20->ds18b20_class);
    cdev_del(&ds18b20->ds18b20_cdev);
    unregister_chrdev_region(ds18b20->dev_num, 1);
    kfree(ds18b20);
    platform_driver_unregister(&ds18b20_driver);
}

module_init(ds18b20_init);
module_exit(ds18b20_exit);
MODULE_LICENSE("GPL");

165.2 应用程序编写

在上一小节中编写了ioctl通过ioctl设置DS18B20获取采集温度分辨率的程序,而ioctl需要跟用户空间的应用程序相配合才能进行使用,所以在本小节将编写测试用的应用程序,编写好的测试程序存放位置为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\100_ds18b20_07\02_app

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <stdlib.h>

#define SET_RESOLUTION _IOW('A', '0', int)
#define READ_RESOLUTION _IOR('A', '1', int)

/**
 * 根据传感器读取的原始数据计算温度值
 * @param value 传感器读取的原始数据
 */
void ds18b20_get_temp(int value) {
    char sig;   // 温度正负号
    float temp; // 温度值

    // 判断温度正负号
    if ((value >> 11) & 0x01) {
        sig = '-';
        value = ~value + 1;
        value &= ~(0xf8 << 8);
    } else {
        sig = '+';
    }

    // 计算温度值
    temp = value * 0.0625;

    // 打印温度信息
    printf("温度为 %c%.4f\n", sig, temp);
}


/**
 * 根据传感器分辨率值打印分辨率信息
 * @param value 传感器分辨率值
 */
void ds18b20_get_resolution(int value) {
    switch (value) {
        case 0x1F:
            printf("分辨率为 9 位\n");
            break;
        case 0x3F:
            printf("分辨率为 10 位\n");
            break;
        case 0x5F:
            printf("分辨率为 11 位\n");
            break;
        case 0x7F:
            printf("分辨率为 12 位\n");
            break;
        default:
            break;
    }
}

int main(int argc, char *argv[]) {
    int fd;    // 文件描述符
    int data;  // 读取的数据
    int args;  // 参数值
    int resolution;  // 返回的分辨率的值

    // 打开设备文件
    fd = open("/dev/ds18b20", O_RDWR);
    if (fd < 0) {
        printf("打开设备文件出错\n");
        return -1;
    }

    // 获取命令行参数
    args = atoi(argv[1]);
    printf("参数值为 %d\n", args);

    // 检查参数范围
    if (args < 9 || args > 12) {
        printf("错误!参数范围应为 9 - 12\n");
        return -1;
    }

    // 设置分辨率
    ioctl(fd, SET_RESOLUTION, args);

    // 读取分辨率
    ioctl(fd, READ_RESOLUTION, &resolution);
    ds18b20_get_resolution(resolution);
    while (1) {
        // 读取数据
        read(fd, &data, sizeof(data));

        // 处理并打印温度信息
        ds18b20_get_temp(data);
    }

    return 0;
}

165.3 运行测试

165.3.1 编译驱动程序

在上一小节中的de18b20.c代码同一目录下创建 Makefile 文件,Makefile 文件内容如下所示:

export ARCH=arm64#设置平台架构
export CROSS_COMPILE=aarch64-linux-gnu-#交叉编译器前缀
obj-m +=ds18b20.o    #此处要和你的驱动源文件同名
KDIR :=/home/topeet/Linux/linux_sdk/kernel    #这里是你的内核目录                                                                                                                            
PWD ?= $(shell pwd)
all:
    make -C $(KDIR) M=$(PWD) modules    #make操作
clean:
    make -C $(KDIR) M=$(PWD) clean    #make clean操作

对于Makefile的内容注释已在上图添加,保存退出之后,来到存放ds18b20.c和Makefile文件目录下,如下图所示:

然后使用命令“make”进行驱动的编译,编译完成如下图所示:

编译完生成ds18b20.ko目标文件,如下图所示:

至此驱动模块就编译成功了。

165.3.2 编译应用程序

首先进行应用程序的编译,因为测试APP是要在开发板上运行的,所以需要aarch64-linux-gnu-gcc来编译,输入以下命令,编译完成以后会生成一个app的可执行程序,如下图所示:

 aarch64-linux-gnu-gcc app.c -o app

然后将编译完成的可执行程序拷贝到开发板上。

165.3.3 运行测试

首先启动开发板,进入系统之后如下所示:

然后将上两个小节编译完成的ds18b20.ko驱动和可执行程序app文件拷贝到开发板上,拷贝完成如下所示:

然后使用以下命令进行驱动的加载,如下图所示:

 insmod ds18b20.ko

 

然后使用以下命令运行可执行程序app,设置分辨率为9位,然后打印采集到的温度,如下图所示:

 ./app 9

 

第一个打印表示我们的传入参数9,第二个打印为通过ioctl获取得到的ds18b20的温度分辨率,可以看到设置和和通过ioctl获取的分辨率相同,且后面得到的温度确实为9位分辨率,证明试验成功,至此,关于通过ioctl获取ds18b20温度采集分辨率的实验就完成了。

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

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

相关文章

门户系统商城模块

商城系统&#xff1a;快递商品本地团购到店核销购物场景全覆盖&#xff0c;全新商销解决方案 商城系统是指一套用于构建和运营电商平台的软件系统&#xff0c;可以帮助企业快速搭建网上商城&#xff0c;实现商品销售、订单管理、客户服务等功能。 商城系统的功能&#xff1a;…

蓝桥杯-dfs搜索模板题(二)

蓝桥杯-dfs搜索模板题&#xff08;二&#xff09; P1683 入门P1596[USACO10OCT] Lake Counting S1114 棋盘 acwingP1025 [NOIP2001 提高组] 数的划分P1019 [NOIP2000 提高组] 单词接龙结语 P1683 入门 这道题没有回溯的必要&#xff0c;重复走也不计数。最开始的部分要补上。 …

UTAustin最新提出!无相机姿态40秒重建3DGS方法

作者&#xff1a;小柠檬 | 来源&#xff1a;3DCV 在公众号「3DCV」后台&#xff0c;回复「原论文」可获取论文pdf 添加微信&#xff1a;dddvision&#xff0c;备注&#xff1a;3D高斯&#xff0c;拉你入群。文末附行业细分群 详细内容请关注3DCV 3D视觉精品课程&#xff1a;…

lombok与idea版本不兼容问题解决

lombok与idea版本不兼容问题&#xff0c;可以选择更改lombok版本&#xff1b;也可以选择加配置来解决此问题 1、选择 setting->Build,Execution,Deployment->compiler 2、在 Shared build process VM options中加入如下配置&#xff0c;即可解决此问题 -Djps.track.ap.…

uniapp,文字超出几行显示省略号...,展开显示更多

效果图&#xff1a; 代码&#xff1a; <template><view class"text-container"><text class"text-content" click"showDetail">{{ text }}</text><text v-if"showMore" class"view-detail" cli…

Redis 全景图(2)---- 关于 Redis 的三“高”

前言 我们继续写第一篇文章没写完的。其实我也不想将我写的一篇 Redis 文章分成几篇中短文来写&#xff0c;但是没办法&#xff0c;我一次写个1万字&#xff0c;会限流&#xff0c;所以将就一下吧。 上篇文章我用了 Redis 的6大模块这个思路来描绘我脑子中的 Redis。其实这6大…

WPF-基础及进阶扩展合集(持续更新)

目录 一、基础 1、GridSplitter分割线 2、x:static访问资源文件 3、wpf触发器 4、添加xaml资源文件 5、Convert转换器 6、多路绑定与多路转换器 二、进阶扩展 1、HierarchicalDataTemplate 2、XmlDataProvider从外部文件获取源 3、TextBox在CellTemplate中的焦点问题…

这些策略助力打造多元化、公平和包容性招聘流程

多样性、公平和包容(DEI)是企业招聘员工的最佳策略。顾名思义&#xff0c;DEI描述了三个关键组成部分: “多元化”&#xff0c;这取决于吸引、招聘、雇佣和留住多元化的员工队伍; “公平”部分是指确保不歧视和平等就业机会; “包容”要求建立一个尊重、支持和包容的环境&am…

【学习】兼容性测试为何如此重要

兼容性测试是软件测试中非常重要的一环&#xff0c;旨在确保软件在不同的平台、浏览器、操作系统等环境下能够正常运行&#xff0c;并且不会出现兼容性问题。本文将介绍兼容性测试的概念、重要性、实施步骤及实践案例&#xff0c;帮助读者更好地理解兼容性测试在软件开发中的重…

【解决问题】排查linux手动删除文件,但是文件标记为deleted,资源未释放

背景&#xff1a; 生产环境我们把程序生成的数据文件手动删除后&#xff0c;但是空间并没有释放&#xff0c;导致硬盘被占用&#xff0c;不够用 问题排查&#xff1a; 1.查看占用文件状态 使用命令&#xff1a; lsof | grep deleted 查看 文件已经删除了&#xff0c;但是都是…

人事管理系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)请假加班招聘考勤

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读300套最新项目持续更新中..... 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含ja…

idea编译一直失败处理

切换分支的时候&#xff0c;明明代码正常&#xff0c;但是编译的时候一直失败。。。。特别是多个项目的时候&#xff0c;经常失败。 配置 -Djps.track.ap.dependenciesfalse idea默认是增量编译&#xff0c;设置这个false之后就从头开始编译了。 设置之后&#xff0c;点击编译&…

Linux系统中安装一些常用的插件备用

Linux系统中安装一些常用的插件备用 1.安装wget yum -y install wget 2.安装vim yum -y install vim-enhanced 3.更换yum源为国内的阿里云源&#xff08;选择&#xff09; 1、备份CentOS-Base.repo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.…

划重点!实物黄金和现货黄金的区别

有人说虽然现货黄金不是实物黄金&#xff0c;但却胜于实物黄金&#xff0c;我们认为如果从投资的便利性&#xff0c;以及潜的获利空间这两个主要的方面来说&#xff0c;上述的观点是相当正确的。但投资者在正式参与之前&#xff0c;最好还是认真了解一下实物黄金和现货黄金的主…

建立统一网络身份认证平台,赋能用户信息安全

“近年来&#xff0c;层出不穷的网络谣言、网络暴力事件以及网络水军、网络黑灰产犯罪屡禁不止、屡打不绝&#xff0c;其主要原因是网络实名制落实不到位。”全国人大代表、黑龙江省大庆市公安局网络警察分局副局长贾晓亮接受记者采访时表示&#xff0c;网络信息安全问题是我们…

深度学习实战74-基于Transformer的ViT模型的搭建与实际应用,ViT模型的原理介绍

大家好,我是微学AI,今天给大家介绍一下深度学习实战74-基于Transformer的ViT模型的搭建与实际应用,ViT模型的原理介绍。Vision Transformer (ViT)是一种基于Transformer架构的深度学习模型,专门用于计算机视觉任务。与传统的卷积神经网络不同,ViT将输入图像分割成固定大小…

【C++】入门知识

1. 命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称都将存在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的就是对标识符的名称进行本地化&#xff0c;以避免命名冲突或名字污染&#xff0c;…

外汇110:交易中,是否真的存在确定性?

我们看问题的角度不同&#xff0c;得到的结果必然也是不一样的。我们不能否认任何一种可能性&#xff0c;但一切需要从逻辑出发。交易中&#xff0c;最大的确定性就是市场是不确定的&#xff0c;什么样的行情都可能发生。当然&#xff0c;绝对的确定性是不存在的&#xff0c;但…

制定合理的薪酬计划是激励员工的最佳方式

想要在竞争日益激烈的环境中取得成功的雇主必须有一个精心设计的薪酬计划&#xff0c;以激励员工&#xff0c;控制薪酬成本&#xff0c;并确保公平&#xff0c;最好的薪酬计划反映了雇主的文化&#xff0c;因此&#xff0c;雇主应该建立一种薪酬理念&#xff0c;福利项目也应该…

Mysql实战--为什么表数据删掉一半,表文件大小不变

经常会有同学来问我&#xff0c;我的数据库占用空间太大&#xff0c;我把一个最大的表删掉了一半的数据&#xff0c;怎么表文件的大小还是没变&#xff1f; 那么今天&#xff0c;我就和你聊聊数据库表的空间回收&#xff0c;看看如何解决这个问题。 这里&#xff0c;我们还是针…