国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

micro_ros移植到STM32F405RG ,micro_ros STM32裸機(jī)

這篇具有很好參考價(jià)值的文章主要介紹了micro_ros移植到STM32F405RG ,micro_ros STM32裸機(jī)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

測(cè)試日期:2023年11月28日
工具鏈:STM32CubeIDE++GCC
參考資料:micro_ros_stm32cubemx_utils
注:本文內(nèi)容僅用于學(xué)習(xí)參考,不適用于生產(chǎn)環(huán)境。
1、準(zhǔn)備工作
1.1、安裝STM32CubeIDE和STM32CubeMX
1.2、準(zhǔn)備mirco_ros 支持cortex-m4的靜態(tài)庫(kù),生成方法可參考我的一篇博文,或者直接下載地址
1.3、下載 micro_ros_stm32cubemx_utils

2、移植過(guò)程
2.1、創(chuàng)建STM32CubeMX項(xiàng)目選擇芯片為STM32F405RGT6
2.2、工程配置
2.2.1、填寫(xiě)工程名稱(chēng)的路徑
2.2.2、Toolchain/IDE配置:STM32CubeIDE

2.3、基本配置
2.3.1、時(shí)鐘配置,根據(jù)開(kāi)發(fā)板配置時(shí)鐘源為外部8MHZ,系統(tǒng)時(shí)鐘168M。
2.3.2、開(kāi)啟SW調(diào)試功能
2.3.3、調(diào)整堆棧大小
stm32移植ros,ROS2,單片機(jī),stm32,嵌入式硬件,單片機(jī)
2.4、配置外設(shè)
2.4.1、配置USART1 異步模式,波特率921600bps 8N1 用于printf輸出
2.4.2、配置USART2 異步模式,波特率115200bps 8N1 使能DMA收發(fā)和全局中斷 用于mirco_ros 通訊接口
2.4.3、根據(jù)開(kāi)發(fā)板配置PD2和PA15為輸出,對(duì)應(yīng)LED3和LED2
2.4.4、配置TIM13定時(shí)1ms并開(kāi)啟更新中斷,用于mirco_ros計(jì)時(shí)
stm32移植ros,ROS2,單片機(jī),stm32,嵌入式硬件,單片機(jī)
2.5、生成代碼,并使用CubeIDE打開(kāi)工程
stm32移植ros,ROS2,單片機(jī),stm32,嵌入式硬件,單片機(jī)
2.6、復(fù)制文件
2.6.1、復(fù)制extra_sources文件夾工作空間
復(fù)制micro_ros_stm32cubemx_utils\extra_sources文件夾到CubeIDE工作空間的Core文件夾。我們只使用USART2的DMA傳輸方式作為mirco_ros接口,因此需要禁用或者刪除it_transport.c和usb_cdc_transport.c文件
custom_memory_manager.c文件在freertos上實(shí)現(xiàn)了內(nèi)存分配,因?yàn)橐某陕銠C(jī)所以先禁用編譯或者直接刪除
stm32移植ros,ROS2,單片機(jī),stm32,嵌入式硬件,單片機(jī)
extra_sources目錄下文件說(shuō)明:
(1)、microros_transports文件夾:與硬件相關(guān)的通訊接口實(shí)現(xiàn),3個(gè)C文件分別提供了串口中斷、串口DMA和USB虛擬串口傳輸案列,這里我們只用到串口DMA傳輸,即dma_transport.c
(2)、custom_memory_manager.c和microros_allocators.c 提供了microros的內(nèi)寸分配接口實(shí)現(xiàn)
(3)、microros_time.c 提供了microros的時(shí)間相關(guān)接口實(shí)現(xiàn)

2.6.2、將靜態(tài)庫(kù)文件和頭文件復(fù)制到工作空間
這里直接把M4lib文件夾直接復(fù)制到Core目錄,然后禁用編譯它們。這一步主要是方便后續(xù)引用,不一定要復(fù)制進(jìn)來(lái)。
stm32移植ros,ROS2,單片機(jī),stm32,嵌入式硬件,單片機(jī)
2.6.3、添加頭文件路徑
右鍵項(xiàng)目->Properties->C/C++Build->Setings->MCU GCC Compiler->include paths 點(diǎn)擊右邊的+圖標(biāo)選擇工作空間下的/Core/M4lib/include 文件夾添加頭文件路徑。
stm32移植ros,ROS2,單片機(jī),stm32,嵌入式硬件,單片機(jī)

2.6.4、添加靜態(tài)庫(kù)文件和路徑
右鍵項(xiàng)目->Properties->C/C++Build->Setings->MCU GCC linker->Library search path(-L) 點(diǎn)擊右邊的+圖標(biāo)選擇工作空間下的/Core/M4lib 文件夾添加庫(kù)文件路徑,在Libraries(-l) 下添加庫(kù)文件名microros,注意庫(kù)文件名在文件夾下為libmicroros.a,GCC連接器-l選項(xiàng)自動(dòng)添加前面的lib字符和后綴名,因此只需要填寫(xiě)microros
stm32移植ros,ROS2,單片機(jī),stm32,嵌入式硬件,單片機(jī)
2.7、修改文件
2.7.1、刪除dma_transport.c文件中與freertos相關(guān)的無(wú)用到代碼,然后在DMA接收完成中斷回調(diào)中重新啟動(dòng)接收,否則程序運(yùn)行一段時(shí)間后打印Error publishing (line xxx)\n。修改后內(nèi)容如下

#include <uxr/client/transport.h>
#include <rmw_microxrcedds_c/config.h>
#include "main.h"
#include "usart.h"
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#ifdef RMW_UXRCE_TRANSPORT_CUSTOM
// --- micro-ROS Transports ---
#define UART_DMA_BUFFER_SIZE 2048

static uint8_t dma_buffer[UART_DMA_BUFFER_SIZE];
static size_t dma_head = 0, dma_tail = 0;
bool cubemx_transport_open(struct uxrCustomTransport * transport){
    UART_HandleTypeDef * uart = (UART_HandleTypeDef*) transport->args;
    HAL_UART_Receive_DMA(uart, dma_buffer, UART_DMA_BUFFER_SIZE);
    return true;
}

bool cubemx_transport_close(struct uxrCustomTransport * transport){
    UART_HandleTypeDef * uart = (UART_HandleTypeDef*) transport->args;
    HAL_UART_DMAStop(uart);
    return true;
}
size_t cubemx_transport_write(struct uxrCustomTransport* transport, uint8_t * buf, size_t len, uint8_t * err){
    UART_HandleTypeDef * uart = (UART_HandleTypeDef*) transport->args;

    HAL_StatusTypeDef ret;
    if (uart->gState == HAL_UART_STATE_READY){
        ret = HAL_UART_Transmit_DMA(uart, buf, len);
        while (ret == HAL_OK && uart->gState != HAL_UART_STATE_READY){
         HAL_Delay(1);
        }
        return (ret == HAL_OK) ? len : 0;
    }else{
        return 0;
    }
}
size_t cubemx_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err){
    UART_HandleTypeDef * uart = (UART_HandleTypeDef*) transport->args;
    int ms_used = 0;
    do
    {
        __disable_irq();
        dma_tail = UART_DMA_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(uart->hdmarx);
        __enable_irq();
        ms_used++;
        HAL_Delay(1);
    } while (dma_head == dma_tail && ms_used < timeout);
    
    size_t wrote = 0;
    while ((dma_head != dma_tail) && (wrote < len)){
        buf[wrote] = dma_buffer[dma_head];
        dma_head = (dma_head + 1) % UART_DMA_BUFFER_SIZE;
        wrote++;
    }
    
    return wrote;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart==&huart2)
	{
		HAL_UART_Receive_DMA(&huart2, dma_buffer, UART_DMA_BUFFER_SIZE);
	}
}
#endif //RMW_UXRCE_TRANSPORT_CUSTOM

2.7.2、修改microros_allocators.c,動(dòng)態(tài)內(nèi)存分配直接使用標(biāo)準(zhǔn)庫(kù)函數(shù) malloc free等,修改后文件如下

#include <unistd.h>
#include <stdlib.h>

void *pvPortMallocMicroROS( size_t xWantedSize );
void vPortFreeMicroROS( void *pv );
void *pvPortReallocMicroROS( void *pv, size_t xWantedSize );
//size_t getBlockSize( void *pv );
void *pvPortCallocMicroROS( size_t num, size_t xWantedSize );

void * microros_allocate(size_t size, void * state){
  (void) state;
  // printf("-- Alloc %d (prev: %d B)\n",size, xPortGetFreeHeapSize());
  return malloc(size);
}
void microros_deallocate(void * pointer, void * state){
  (void) state;
  // printf("-- Free %d (prev: %d B)\n",getBlockSize(pointer), xPortGetFreeHeapSize());
  if (NULL != pointer){
    free(pointer);
  }
}
void * microros_reallocate(void * pointer, size_t size, void * state){
  (void) state;
  // printf("-- Realloc %d -> %d (prev: %d B)\n",getBlockSize(pointer),size, xPortGetFreeHeapSize());

  if (NULL == pointer){
    return malloc(size);
  } else {
    return realloc(pointer,size);
  }
}
void * microros_zero_allocate(size_t number_of_elements, size_t size_of_element, void * state){
  (void) state;
  // printf("-- Calloc %d x %d = %d -> (prev: %d B)\n",number_of_elements,size_of_element, number_of_elements*size_of_element, xPortGetFreeHeapSize());
  return calloc(number_of_elements,size_of_element);
}

2.7.3、修改main.c 文件
定義一個(gè)uint32類(lèi)型全局變量ullTickCount

uint32_t ullTickCount;

在while循環(huán)前啟動(dòng)定時(shí)器13

  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim13);
  /* USER CODE END 2 */

在定時(shí)器13更新中斷中讓ullTickCount自加1,計(jì)數(shù)總毫秒數(shù)

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim==&htim13)
	{
		ullTickCount++;		
	}
}
/* USER CODE END 4 */

2.7.4、添加頭文件包含
在main.c合適位置添加以下內(nèi)容

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>
#include <uxr/client/transport.h>
#include <rmw_microxrcedds_c/config.h>
#include <rmw_microros/rmw_microros.h>

#include <std_msgs/msg/int32.h>
/* USER CODE END Includes */

2.7.5、添加前置聲明

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
bool cubemx_transport_open(struct uxrCustomTransport * transport);
bool cubemx_transport_close(struct uxrCustomTransport * transport);
size_t cubemx_transport_write(struct uxrCustomTransport* transport, const uint8_t * buf, size_t len, uint8_t * err);
size_t cubemx_transport_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err);

void * microros_allocate(size_t size, void * state);
void microros_deallocate(void * pointer, void * state);
void * microros_reallocate(void * pointer, size_t size, void * state);
void * microros_zero_allocate(size_t number_of_elements, size_t size_of_element, void * state);
/* USER CODE END FunctionPrototypes */

2.7.5、在while前添加mirco_ros 節(jié)點(diǎn)的初始化

	// micro-ROS configuration

	  rmw_uros_set_custom_transport(
	    true,
	    (void *) &huart2,
	    cubemx_transport_open,
	    cubemx_transport_close,
	    cubemx_transport_write,
	    cubemx_transport_read);

	  rcl_allocator_t freeRTOS_allocator = rcutils_get_zero_initialized_allocator();
	  freeRTOS_allocator.allocate = microros_allocate;
	  freeRTOS_allocator.deallocate = microros_deallocate;
	  freeRTOS_allocator.reallocate = microros_reallocate;
	  freeRTOS_allocator.zero_allocate =  microros_zero_allocate;

	  if (!rcutils_set_default_allocator(&freeRTOS_allocator)) {
	      printf("Error on default allocators (line %d)\n", __LINE__);
	  }

	  // micro-ROS app

	  rcl_publisher_t publisher;
	  std_msgs__msg__Int32 msg;
	  rclc_support_t support;
	  rcl_allocator_t allocator;
	  rcl_node_t node;

	  allocator = rcl_get_default_allocator();

	  //create init_options
	  rclc_support_init(&support, 0, NULL, &allocator);

	  // create node
	  rclc_node_init_default(&node, "cubemx_node", "", &support);

	  // create publisher
	  rclc_publisher_init_default(
	    &publisher,
	    &node,
	    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
	    "cubemx_publisher");

	  msg.data = 0;

2.7.6、在while中添加數(shù)據(jù)發(fā)布

  /* USER CODE BEGIN WHILE */
  while (1)
  {
	    rcl_ret_t ret = rcl_publish(&publisher, &msg, NULL);
	    if (ret != RCL_RET_OK)
	    {
	      printf("Error publishing (line %d)\n", __LINE__);
	    }
	    msg.data++;
	    HAL_Delay(10);

    /* USER CODE END WHILE */
  }

2.7.7、修改microros_time.c文件
添加 #define configTICK_RATE_HZ 1000LL
將ullTickCount 傳遞給UTILS_NanosecondsToTimespec函數(shù)
更改后代碼

#include <unistd.h>
#include <time.h>

#define configTICK_RATE_HZ 1000LL
#define MICROSECONDS_PER_SECOND    ( 1000000LL )                                   /**< Microseconds per second. */
#define NANOSECONDS_PER_SECOND     ( 1000000000LL )                                /**< Nanoseconds per second. */
#define NANOSECONDS_PER_TICK       ( NANOSECONDS_PER_SECOND / configTICK_RATE_HZ ) /**< Nanoseconds per FreeRTOS tick. */

void UTILS_NanosecondsToTimespec( int64_t llSource,
                                  struct timespec * const pxDestination )
{
    long lCarrySec = 0;

    /* Convert to timespec. */
    pxDestination->tv_sec = ( time_t ) ( llSource / NANOSECONDS_PER_SECOND );
    pxDestination->tv_nsec = ( long ) ( llSource % NANOSECONDS_PER_SECOND );

    /* Subtract from tv_sec if tv_nsec < 0. */
    if( pxDestination->tv_nsec < 0L )
    {
        /* Compute the number of seconds to carry. */
        lCarrySec = ( pxDestination->tv_nsec / ( long ) NANOSECONDS_PER_SECOND ) + 1L;

        pxDestination->tv_sec -= ( time_t ) ( lCarrySec );
        pxDestination->tv_nsec += lCarrySec * ( long ) NANOSECONDS_PER_SECOND;
    }
}

int clock_gettime( int clock_id,
                   struct timespec * tp )
{
    /* Convert ullTickCount to timespec. */
    extern uint32_t ullTickCount;
    UTILS_NanosecondsToTimespec( ( int64_t ) ullTickCount * NANOSECONDS_PER_TICK, tp );
    return 0;
}

2.7.8、添加串口printf打印支持

#include "stdio.h"
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
PUTCHAR_PROTOTYPE
{
    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}

編譯無(wú)報(bào)錯(cuò),自此移植完成!

3、下載測(cè)試
參考micro_ros移植到STM32F405RG 測(cè)試部分文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-798674.html

到了這里,關(guān)于micro_ros移植到STM32F405RG ,micro_ros STM32裸機(jī)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【ROS2】install micro_ros

    【ROS2】install micro_ros

    本文參考b站up:“照祥同學(xué)”的教程來(lái)的,中間一些細(xì)節(jié)的操作謹(jǐn)以此文作為補(bǔ)充,或者說(shuō)是我在按照教程走的時(shí)候遇到的問(wèn)題記錄。視頻鏈接:第二節(jié):安裝micro_ros 的 Arduino 開(kāi)發(fā)環(huán)境_嗶哩嗶哩_bilibili 根據(jù)照祥同學(xué)里面說(shuō)的魚(yú)香ros的一鍵配置rosdep即可。 安裝成功。 繼續(xù)按

    2024年02月06日
    瀏覽(13)
  • GD32F4移植STM32F4

    GD32F4移植STM32F4

    近期在項(xiàng)目中采用了GD32F407VET6替換原項(xiàng)目中的STM32F407VET6,網(wǎng)傳GD的兼容性很好,之前也用F1系統(tǒng)的替換了一下,按照CSND各位大佬的經(jīng)驗(yàn)一步步改進(jìn)了代碼,測(cè)試直接通過(guò),現(xiàn)在也一直在項(xiàng)目中實(shí)際應(yīng)用了,一直沒(méi)有出問(wèn)題。 所以這SMT時(shí),嘉立創(chuàng)沒(méi)有STM的貨果斷換成了GD,可換時(shí)

    2024年02月16日
    瀏覽(32)
  • STM32G473VET6 FlashDB數(shù)據(jù)庫(kù)移植(裸機(jī)、片內(nèi)Flash)

    STM32G473VET6 FlashDB數(shù)據(jù)庫(kù)移植(裸機(jī)、片內(nèi)Flash)

    此文檔也適用于STM32G070 此處使用FlashDB官方最新源碼 FlashDB: 一款支持 KV 數(shù)據(jù)和時(shí)序數(shù)據(jù)的超輕量級(jí)數(shù)據(jù)庫(kù) (gitee.com) 克隆源碼后目錄如下 紅框中幾個(gè)為移植必要文件與參考 根據(jù)FlashDB官方文檔可知,F(xiàn)lashDB底層依賴(lài)于RT-Thread的FAL組件,所以需要先移植FAL FlashDB源碼中port目錄下即

    2024年01月21日
    瀏覽(56)
  • STM32F407 移植 FreeRTOS

    STM32F407 移植 FreeRTOS

    本實(shí)驗(yàn)是基于正點(diǎn)原子 STM32F407ZG 探索者開(kāi)發(fā)板完成的,所以需要一個(gè)STM32F407ZG 探索者開(kāi)發(fā)板 用于移植的基礎(chǔ)工程(下面會(huì)講) FreeRTOS源碼(下面會(huì)講) 本實(shí)驗(yàn)所有用到的代碼:基于正點(diǎn)原子STM32F407的FreeRTOS移植工程.zip 1.1 移植前準(zhǔn)備 1.1.1 基礎(chǔ)工程 由于后續(xù)需要用到 LED、

    2024年02月08日
    瀏覽(28)
  • STM32F429移植microPython筆記

    STM32F429移植microPython筆記

    https://micropython.org/download/官網(wǎng) 下載后放在linux中。 解壓命令: 進(jìn)入micropython目錄下,進(jìn)入mpy-cross目錄,先編譯MicroPython cross-compiler,在終端輸入: 進(jìn)入/ports/stm32/boards目錄中,將目錄STM32F429DISC拷貝一份為MY_STM32F429DISC。 然后進(jìn)入MY_STM32F429DISC目錄中修改mpconfigboard.h和stm32f4xx_ha

    2024年02月01日
    瀏覽(21)
  • [GD32F4]基于GD32固件庫(kù)移植cherryusb[STM32F4]

    [GD32F4]基于GD32固件庫(kù)移植cherryusb[STM32F4]

    [GD32F4]基于GD32固件庫(kù)移植cherryusb[STM32F4] 使用開(kāi)發(fā)板是淘寶買(mǎi)的不知名開(kāi)發(fā)板,沒(méi)什么好說(shuō)的,具體的型號(hào)是GD32F450VET6。 使用的cherryusb版本是0.9.0版本。 使用的GD32官方固件庫(kù)版本是:GD32F4xx_Firmware_Library_V3.0.4 cherryusb最牛的地方在于拋棄掉所有的依賴(lài),只需要知道芯片的usb中斷

    2024年02月06日
    瀏覽(69)
  • GD32F470 移植STM32F429工程 Keil調(diào)試筆記

    GD32F470 移植STM32F429工程 Keil調(diào)試筆記

    keil版本:5.25 安裝 GigaDevice.GD32F4xx_DFP.3.0.4.pack Keil.STM32F4xx_DFP.2.15.0.pack 1、原項(xiàng)目為STM32F429 工程,切換到GD32F470 只需在 Options for Target\\\"“對(duì)話框的Device菜單中選中“GD32F470II”,重新編譯即可,一般不會(huì)有編譯錯(cuò)誤。 2、將項(xiàng)目工程在切換回STM32F429,在 Options for Target”\\\"對(duì)話框的D

    2024年02月09日
    瀏覽(24)
  • STM32F407移植OpenHarmony筆記1

    參考文檔: OpenAtom OpenHarmony width=device-width,initial-scale=1.0 https://docs.openharmony.cn/pages/v3.2/zh-cn/device-dev/get-code/gettools-acquire.md/ 搭建環(huán)境 安裝linux系統(tǒng): Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-91-generic x86_64) 下載源代碼:我選擇的是V3.2.4版本 https://repo.huaweicloud.com/openharmony/os/3.2.4/code-v3.2.4-Rele

    2024年01月25日
    瀏覽(24)
  • FreeRTOS移植STM32超詳細(xì)(以STM32F103ZE為例)

    FreeRTOS移植STM32超詳細(xì)(以STM32F103ZE為例)

    我剛學(xué)FreeROTS時(shí)想移植到STM32,找了網(wǎng)上很多資料,但大多都不是很完整,于是我把我自己的移植過(guò)程分享出來(lái),供大家參考。 我們以STM32F103ZE,正點(diǎn)原子的跑馬燈實(shí)驗(yàn)為例, 準(zhǔn)備工作: 跑馬燈實(shí)驗(yàn)工程 FreeRTOS文件源碼(可在官方下載) ? ? 第一步? 移植文件到工程 首先在工

    2024年02月08日
    瀏覽(21)
  • 基于STM32F4的CANOpen移植教程(超級(jí)詳細(xì))

    基于STM32F4的CANOpen移植教程(超級(jí)詳細(xì))

    本專(zhuān)題相關(guān)教程: 基于STM32F4的CANOpen移植教程 基于STM32F4的CANopen快速SDO通信 linux下CANopen for python的使用 基于Linux C的CANopen移植 CANopen補(bǔ)充–時(shí)間計(jì)算出錯(cuò) CANopen補(bǔ)充–主站檢測(cè)節(jié)點(diǎn)是否在線 為了在STM32F4上能夠運(yùn)行CANopen(CanFestival),跟著網(wǎng)上的教程操作,發(fā)現(xiàn)總是不夠詳細(xì)。

    2024年02月02日
    瀏覽(29)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包