【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】HAL移植

这篇具有很好参考价值的文章主要介绍了【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】HAL移植。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、环境介绍

RK3588主板搭载Android12操作系统,内核是Linux5.10,使用ST的六轴传感器LSM6DSR芯片。

二、芯片介绍

LSM6DSR是一款加速度和角速度(陀螺仪)六轴传感器,还内置了一个温度传感器。该芯片可以选择I2C,SPI通讯,还有可编程终端,可以后置摄像头等设备,功能是很强大的(感兴趣的可以去看数据手册)。该芯片原厂公开了input和iio两种驱动和HAL,我这边选用的是iio驱动,所以HAL也配套选择了iio的。

三、驱动移植

【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】驱动移植__花花的博客-CSDN博客

四、HAL移植

源码链接:https://github.com/STMicroelectronics/STMems_Android_Sensor_HAL_IIO/tree/STMems_Android_Sensor_HAL_IIO

1,拷贝整个文件夹到hardware/目录下

【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】HAL移植,Android,驱动开发,android,linux

2,在/device/rockchip/rk3588/device.mk中增加

PRODUCT_PACKAGES += sensors.rk3588

3,HAL目录下,执行生成cofig指令

source android_data_config
make sensors-defconfig

        报错失败可以参考【android12-linux-5.1】【ST芯片】HAL移植后配置文件生成报错__花花的博客-CSDN博客

4,增加权限配置参考(开机会卡住报错-13)

【android12-linux-5.1】【ST芯片】HAL移植后开机卡死__花花的博客-CSDN博客

5,编译后调不到HAL参考(HAL增加日志不会出来)

【android12-linux-5.1】【ST芯片】HAL移植后没调起来__花花的博客-CSDN博客

6,多HAL兼容参考

RK平台的sensor框架HAL层兼容其他HAL层so库__花花的博客-CSDN博客

7,测试任然SensorManger调不到的话,参考配置

Solved: Re: Android P can't get LSM6DSM HAL Accelerometer/... - STMicroelectronics Community

五,测试

直接系统接口SensorManger调用即可

1,MainActivity.java

package com.example.sensorsdata;

import static android.hardware.SensorManager.SENSOR_DELAY_GAME;
import static android.hardware.SensorManager.SENSOR_DELAY_NORMAL;
import static android.hardware.SensorManager.SENSOR_DELAY_UI;
import static java.lang.Math.atan2;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;

import com.google.android.material.snackbar.Snackbar;

import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Environment;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;

import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.TextView;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

public class MainActivityRaw extends Activity implements SensorEventListener {

    private SensorManager sensorManager = null;
    private Sensor accSensor = null;//加速度传感器
    private Sensor gyroSensor = null;//角速度传感器
    private Sensor magSensor = null;//磁力传感器
    private Sensor stepSensor = null;//计步传感器
    private Sensor tempSensor = null;//温度传感器
    private Sensor tempSensor2 = null;//温度传感器
    private TextView textView_AccName, textView_AccX, textView_AccY, textView_AccZ;//加速度传感器参数
    private TextView textView_GyrName, textView_GyrX, textView_GyrY, textView_GyrZ;//角速度传感器参数
    private TextView textView_MagName, textView_MagX, textView_MagY, textView_MagZ;//磁力传感器参数
    private TextView textView_StepName, textView_StepData;//计步传感器器参数
    private TextView textView_TempName, textView_TempData;//温度传感器器参数
    private TextView textView_TempName2, textView_TempData2;//温度传感器器参数
    private String strAppName = "SensorData";

    private TextView v;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView_AccName = (TextView) findViewById(R.id.acc_name);
        textView_AccX = (TextView) findViewById(R.id.acc_x);
        textView_AccY = (TextView) findViewById(R.id.acc_y);
        textView_AccZ = (TextView) findViewById(R.id.acc_z);
        textView_GyrName = (TextView) findViewById(R.id.gyr_name);
        textView_GyrX = (TextView) findViewById(R.id.gyr_x);
        textView_GyrY = (TextView) findViewById(R.id.gyr_y);
        textView_GyrZ = (TextView) findViewById(R.id.gyr_z);
        textView_MagName = (TextView) findViewById(R.id.mag_name);
        textView_MagX = (TextView) findViewById(R.id.mag_x);
        textView_MagY = (TextView) findViewById(R.id.mag_y);
        textView_MagZ = (TextView) findViewById(R.id.mag_z);
        textView_StepName = (TextView) findViewById(R.id.step_name);
        textView_StepData = (TextView) findViewById(R.id.step_data);
        textView_TempName = (TextView) findViewById(R.id.temp_name);
        textView_TempData = (TextView) findViewById(R.id.temp_data);
        textView_TempName2 = (TextView) findViewById(R.id.temp_name2);
        textView_TempData2 = (TextView) findViewById(R.id.temp_data2);

        v = (TextView) findViewById(R.id.v);

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

        accSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);textView_AccName.setText(accSensor.getName());
        gyroSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);textView_GyrName.setText(gyroSensor.getName());
        magSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);textView_MagName.setText(magSensor.getName());
        stepSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);textView_StepName.setText(stepSensor.getName());
        tempSensor = sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);textView_TempName.setText(tempSensor.getName());

        StringBuffer sb = new StringBuffer();
        List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
        for (Sensor sensor : sensors) {
            sb.append(sensor.toString());
            sb.append("\n");
            Log.i(strAppName, sensor.toString());
            if(sensor.getName().contains("LM75A"))
            {
                tempSensor2 = sensor;textView_TempName2.setText(tempSensor2.getName());
            }
        }
        v.setText(sb.toString());
    }

    @Override
    protected void onPause() {
// TODO Auto-generated method stub
        super.onPause();
        sensorManager.unregisterListener(this); // 解除监听器注册
    }

    @Override
    protected void onResume() {
// TODO Auto-generated method stub
        super.onResume();
        Log.e(strAppName, "registerListener start");
        sensorManager.registerListener(this, accSensor, SENSOR_DELAY_GAME); //为传感器注册监听器
        sensorManager.registerListener(this, gyroSensor, SENSOR_DELAY_GAME); //为传感器注册监听器
        sensorManager.registerListener(this, magSensor, SENSOR_DELAY_GAME); //为传感器注册监听器
        sensorManager.registerListener(this, stepSensor, SENSOR_DELAY_GAME); //为传感器注册监听器
        sensorManager.registerListener(this, tempSensor, SENSOR_DELAY_GAME); //为传感器注册监听器
        sensorManager.registerListener(this, tempSensor2, SENSOR_DELAY_GAME); //为传感器注册监听器
        Log.e(strAppName, "registerListener end");
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub

    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            textView_AccX.setText(String.format("%+.2f", event.values[0]));
            textView_AccY.setText(String.format("%+.2f", event.values[1]));
            textView_AccZ.setText(String.format("%+.2f", event.values[2]));
        }
        else if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
            textView_GyrX.setText(String.format("%+.2f", event.values[0]));
            textView_GyrY.setText(String.format("%+.2f", event.values[1]));
            textView_GyrZ.setText(String.format("%+.2f", event.values[2]));
        }
        else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            textView_MagX.setText(String.format("%+.2f", event.values[0]));
            textView_MagY.setText(String.format("%+.2f", event.values[1]));
            textView_MagZ.setText(String.format("%+.2f", event.values[2]));
        }
        else if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
            textView_StepData.setText(""+event.values[0]);
        }
        else if (event.sensor.getType() == Sensor.TYPE_AMBIENT_TEMPERATURE) {
            if(tempSensor == event.sensor) {
                textView_TempData.setText(String.format("%+.2f", event.values[0]));//75ms
            }
            else {
                textView_TempData2.setText(String.format("%+.2f", event.values[0]));
            }
        }
    }
}

2,activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/acc_name"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_margin="3dp"
            android:textSize="40px" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_marginTop="5dp"
            android:text="X:"
            android:textSize="50px" />
        <TextView
            android:id="@+id/acc_x"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:text="111"
            android:textSize="50px"
            android:textStyle="bold" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_marginTop="5dp"
            android:text="Y:"
            android:textSize="50px" />
        <TextView
            android:id="@+id/acc_y"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:text="111"
            android:textSize="50px"
            android:textStyle="bold"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_marginTop="5dp"
            android:text="Z:"
            android:textSize="50px" />
        <TextView
            android:id="@+id/acc_z"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:text="111"
            android:textSize="50px"
            android:textStyle="bold"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/gyr_name"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_margin="3dp"
            android:textSize="40px" />

        <TextView
            android:layout_marginTop="5dp"
            android:layout_marginLeft="2dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="X:"
            />
        <TextView
            android:layout_margin="5dp"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="111"
            android:id="@+id/gyr_x"
            android:textStyle="bold"/>
        <TextView
            android:layout_marginTop="5dp"
            android:layout_marginLeft="2dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="Y:"
            />
        <TextView
            android:layout_margin="5dp"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="111"
            android:id="@+id/gyr_y"
            android:textStyle="bold"/>
        <TextView
            android:layout_marginTop="5dp"
            android:layout_marginLeft="2dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="Z:"
            />
        <TextView
            android:layout_margin="5dp"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="111"
            android:id="@+id/gyr_z"
            android:textStyle="bold"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/mag_name"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_margin="3dp"
            android:textSize="40px" />
        <TextView
            android:layout_marginTop="5dp"
            android:layout_marginLeft="2dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="X:"
            />
        <TextView
            android:layout_margin="5dp"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="111"
            android:id="@+id/mag_x"
            android:textStyle="bold"/>
        <TextView
            android:layout_marginTop="5dp"
            android:layout_marginLeft="2dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="Y:"
            />
        <TextView
            android:layout_margin="5dp"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="111"
            android:id="@+id/mag_y"
            android:textStyle="bold"/>
        <TextView
            android:layout_marginTop="5dp"
            android:layout_marginLeft="2dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="Z:"
            />
        <TextView
            android:layout_margin="5dp"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:textSize="50px"
            android:text="111"
            android:id="@+id/mag_z"
            android:textStyle="bold"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/step_name"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_margin="3dp"
            android:textSize="40px" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_marginTop="5dp"
            android:text="D:"
            android:textSize="50px" />
        <TextView
            android:id="@+id/step_data"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:text="111"
            android:textSize="50px"
            android:textStyle="bold" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/temp_name"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_margin="3dp"
            android:textSize="40px" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_marginTop="5dp"
            android:text="T:"
            android:textSize="50px" />
        <TextView
            android:id="@+id/temp_data"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:text="111"
            android:textSize="50px"
            android:textStyle="bold" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/temp_name2"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_margin="3dp"
            android:textSize="40px" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_marginTop="5dp"
            android:text="T:"
            android:textSize="50px" />
        <TextView
            android:id="@+id/temp_data2"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:text="111"
            android:textSize="50px"
            android:textStyle="bold" />
    </LinearLayout>

    <TextView
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/v"
        android:textSize="24px"
        android:text="获取传感器列表显示"
        ></TextView>

</LinearLayout>

3,测试效果如下图(不相关的传感器先模糊处理了):直接移植只能看到加速度和角速度传感器,计步器及温度传感器需要修改HAL源码,见下篇。

【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】HAL移植,Android,驱动开发,android,linux

4,数据方向不对处理参考

【android12-linux-5.1】【ST芯片】驱动与HAL移植后数据方向异常__花花的博客-CSDN博客

提示:该HAL于2022年就停止维护了,最新维护源码路径:https://github.com/STMicroelectronics/st-mems-android-linux-sensors-hal 。开始移植的时候完全没头绪,只顾着检测是否能用,没注意维护情况问题,但是该HAL亲测能用。HAL结构及调用分析见下篇。

另,源码包上传资源被拒,提示侵权,需要的可以评论私信我获取。

新人入行,经验分享,如有所误,欢迎指出~

版权归属:深圳市琪智科技有限公司-花花文章来源地址https://www.toymoban.com/news/detail-700844.html

到了这里,关于【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】HAL移植的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RK3588 Android 12 北斗模块调试

    北斗模块用的MTK RS1612M3 , http://www.sragps.com/web/down.html,可以查看相关资料,用串口和系统通讯 Android12中主要包括串口设备树修改,GPS2.0加载,gps.default.so编译和上层应用测试,以下主要记录测试中碰到的难点 板子上用的串口8,因此打开uart8的设备树配置 uart8 { status = “okay”;

    2024年02月15日
    浏览(27)
  • [RK3588 Android12]设置屏幕方向、分辨率和密度

    修改device/rockchip/common/BoardConfig.mk SF_PRIMARY_DISPLAY_ORIENTATIO参数值 在控制台输入 wm size 1920x1080 或 修改device/rockchip/rk3588/rk3588_s/rk3588_s.mk 增加PRODUCT_PROPERTY_OVERRIDES += ro.config.size_override参数值 在控制台输入 wm density 240 或 修改device/rockchip/rk3588/rk3588_s/rk3588_s.mk 修改PRODUCT_PROPERTY_OVERRI

    2024年02月15日
    浏览(40)
  • RK3588平台开发系列讲解(安卓篇)Android12 获取 root 权限

    沉淀、分享、成长,让自己和他人都能有所收获!😄 📢获取 Android 设备的 root 权限是指取得超级用户( root 用户)的权限,使得用户可以对系统进行更广泛的修改和操作。但需要注意,获取 root 权限可能会导致安全风险,包括系统不稳定、数据丢失或设备损坏,因此应该谨

    2024年02月03日
    浏览(50)
  • Android RK3588-12 hdmi-in Camera方式最大支持3个

      hdmi-in Camera最大支持3个     modified:   hardware/interfaces/camera/device/3.4/default/ExternalCameraDevice.cpp     modified:   hardware/interfaces/camera/device/3.4/default/ExternalCameraDeviceSession.cpp     modified:   hardware/interfaces/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h     modified:

    2024年02月08日
    浏览(36)
  • RK3588平台开发系列讲解(USB篇)Linux Android USB软件架构

    平台 内核版本 安卓版本 RK3588 Linux 5.10 Android 12

    2024年02月09日
    浏览(41)
  • RK3588芯片支持8K视频的硬编解码

    RK3588是一款采用8nm制程工艺的高端通用型SoC,CPU采用四核A76和四核A55的八核架构,GPU采用Mail G610MP4,集成6TOPS独立NPU,支持四通道LPDDR5,有效保证了RK3588芯片的性能输出。RK3588在视频编解码方面也十分突出,支持8K视频的硬编硬解,非常适合VR(虚拟现实)、AR(增强现实)、

    2024年02月12日
    浏览(36)
  • 陀螺仪LSM6DSV16X与AI集成(5)----6D方向检测功能

    陀螺仪通常可以读取三个方向上的旋转,即绕X轴、Y轴和Z轴的旋转。每个方向上的旋转包括正向旋转和反向旋转,因此一共有六个位置。这六个位置分别是:1.X轴正向旋转、2.X轴反向旋转、3.Y轴正向旋转、4.Y轴反向旋转、5.Z轴正向旋转、6.Z轴反向旋转 通过检测陀螺仪在每个方

    2024年02月22日
    浏览(33)
  • 【android】rk3588-android-bt

    参考: https://source.android.com/docs/core/connect/bluetooth?hl=zh-cn https://android.googlesource.com/platform/hardware/interfaces/+/master/bluetooth/ 蓝牙整体硬件架构上分为主机(计算机或MCU)和主机控制器(实际蓝牙芯片组)两部分;主机和控制器之间的通信遵循主机控制器接口(HCI),如下所示:

    2024年01月24日
    浏览(29)
  • 陀螺仪LSM6DSV16X与AI集成(3)----读取融合算法输出的四元数

    LSM6DSV16X 特性涉及到的是一种低功耗的传感器融合算法(Sensor Fusion Low Power, SFLP). 低功耗传感器融合(SFLP)算法: 该算法旨在以节能的方式结合加速度计和陀螺仪的数据。传感器融合算法通过结合不同传感器的优势,提供更准确、可靠的数据。 6轴游戏旋转向量: SFLP算法能

    2024年02月03日
    浏览(28)
  • arm鲁班猫lubanCat rk3588 ubuntu20.04下源码编译安装qt5.12.5

    ubuntu-18.04上通过源码来编译及安装Qt-5.12库 QT官方线上文档for linux qt源码下载地址 进入下面目录下载 【new_archive/qt/5.12/5.12.5/single/qt-everywhere-src-5.12.5.tar.xz】 将压缩包放到Ubuntu某目录,并进入解压: 初步解压出:qt-everywhere-src-5.12.5.tar 最终得到:qt-everywhere-src-5.12.5 或者【右键】

    2024年04月11日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包