【问题标题】:How to pass a structure as a parameter when creating a FreeRTOS task?创建 FreeRTOS 任务时如何将结构作为参数传递?
【发布时间】:2022-01-23 01:23:43
【问题描述】:

我目前正在研究 NXP i.MX8 M Mini 处理器的 Cortex-M4。 我正在开发 M4 (OS FreeRTOS) 的应用程序。 我想做的是填充一个结构,创建一个任务,将此结构作为参数传递给此任务并在此任务中重用此结构。

但是,我无法在创建的任务中获取作为参数传递的结构的值。 在编译时,我收到“警告:取消引用 'void *' 指针”或“错误:请求成员 'my_rpmsg' 不是结构或联合”

这是我的代码:

/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2017 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rpmsg_lite.h"
#include "rpmsg_queue.h"
#include "rpmsg_ns.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "FreeRTOS.h"
#include "task.h"

#include "fsl_uart.h"
#include "rsc_table.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define RPMSG_LITE_SHMEM_BASE         (VDEV0_VRING_BASE)
#define RPMSG_LITE_LINK_ID            (RL_PLATFORM_IMX8MM_M4_USER_LINK_ID)
#define RPMSG_LITE_NS_ANNOUNCE_STRING "rpmsg-virtual-tty-channel-1"
#define RPMSG_TASK_STACK_SIZE (256)
#define RPMSG_RX_TASK_STACK_SIZE (256)
#define RPMSG_TX_TASK_STACK_SIZE (256)
#ifndef LOCAL_EPT_ADDR
#define LOCAL_EPT_ADDR (30)
#endif

/* Globals */
static char app_buf[512]; /* Each RPMSG buffer can carry less than 512 payload */

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Code
 ******************************************************************************/
static TaskHandle_t rpmsg_task_handle = NULL;
static TaskHandle_t rpmsg_tx_task_handle = NULL;

struct rpmsg_struct
{
    struct rpmsg_lite_endpoint *volatile my_ept;
    volatile rpmsg_queue_handle my_queue;
    struct rpmsg_lite_instance *volatile my_rpmsg;
};

static void rpmsg_tx_task(void *param)
{
    volatile uint32_t remote_addr;
//    struct rpmsg_lite_endpoint *volatile my_ept;
//    volatile rpmsg_queue_handle my_queue;
//    struct rpmsg_lite_instance *volatile my_rpmsg;
    void *rx_buf;
    uint32_t len;
    int32_t result;
    void *tx_buf;
    uint32_t size;

    /* Print the initial banner */
    PRINTF("\r\nRPMSG String Echo FreeRTOS RTOS API Demo...\r\n");

    for (;;)
    {
        /* Get RPMsg rx buffer with message */
        result =
            rpmsg_queue_recv_nocopy(param->my_rpmsg, param->my_queue, (uint32_t *)&remote_addr, (char **)&rx_buf, &len, RL_BLOCK);
        if (result != 0)
        {
            assert(false);
        }

        /* Copy string from RPMsg rx buffer */
        assert(len < sizeof(app_buf));
        memcpy(app_buf, rx_buf, len);
        app_buf[len] = 0; /* End string by '\0' */

        if ((len == 2) && (app_buf[0] == 0xd) && (app_buf[1] == 0xa))
            PRINTF("Get New Line From Master Side\r\n");
        else
            PRINTF("Get Message From Master Side : \"%s\" [len : %d]\r\n", app_buf, len);

        /* Get tx buffer from RPMsg */
        tx_buf = rpmsg_lite_alloc_tx_buffer(param->my_rpmsg, &size, RL_BLOCK);
        assert(tx_buf);
        /* Copy string to RPMsg tx buffer */
        memcpy(tx_buf, app_buf, len);
        /* Echo back received message with nocopy send */
        result = rpmsg_lite_send_nocopy(param->my_rpmsg, param->my_ept, remote_addr, tx_buf, len);
        if (result != 0)
        {
            assert(false);
        }
        /* Release held RPMsg rx buffer */
        result = rpmsg_queue_nocopy_free(param->my_rpmsg, rx_buf);
        if (result != 0)
        {
            assert(false);
        }
    }
}

static void rpmsg_task(void *param)
{
    static struct rpmsg_struct my_rpmsg_struct;

    /* Print the initial banner */
    PRINTF("\r\nRPMSG String Echo FreeRTOS RTOS API Demo...\r\n");

#ifdef MCMGR_USED
    uint32_t startupData;

    /* Get the startup data */
    (void)MCMGR_GetStartupData(kMCMGR_Core1, &startupData);

    my_rpmsg = rpmsg_lite_remote_init((void *)startupData, RPMSG_LITE_LINK_ID, RL_NO_FLAGS);

    /* Signal the other core we are ready */
    (void)MCMGR_SignalReady(kMCMGR_Core1);
#else
    my_rpmsg_struct.my_rpmsg = rpmsg_lite_remote_init((void *)RPMSG_LITE_SHMEM_BASE, RPMSG_LITE_LINK_ID, RL_NO_FLAGS);
#endif /* MCMGR_USED */

    while (0 == rpmsg_lite_is_link_up(my_rpmsg_struct.my_rpmsg))
        ;

    my_rpmsg_struct.my_queue = rpmsg_queue_create(my_rpmsg_struct.my_rpmsg);
    my_rpmsg_struct.my_ept   = rpmsg_lite_create_ept(my_rpmsg_struct.my_rpmsg, LOCAL_EPT_ADDR, rpmsg_queue_rx_cb, my_rpmsg_struct.my_queue);
    (void)rpmsg_ns_announce(my_rpmsg_struct.my_rpmsg, my_rpmsg_struct.my_ept, RPMSG_LITE_NS_ANNOUNCE_STRING, RL_NS_CREATE);

    PRINTF("\r\nNameservice sent, ready for incoming messages...\r\n");

    if (xTaskCreate(rpmsg_tx_task, "rpmsg_tx_task", RPMSG_TX_TASK_STACK_SIZE, &my_rpmsg_struct, tskIDLE_PRIORITY + 1, &rpmsg_tx_task_handle) != pdPASS)
    {
        PRINTF("\r\nFailed to create rpmsg_tx_task\r\n");
        for (;;)
            ;
    }
}

/*!
 * @brief Main function
 */
int main(void)
{
    /* Initialize standard SDK demo application pins */
    /* Board specific RDC settings */
    BOARD_RdcInit();

    BOARD_InitBootPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();
    BOARD_InitMemory();

    copyResourceTable();

#ifdef MCMGR_USED
    /* Initialize MCMGR before calling its API */
    (void)MCMGR_Init();
#endif /* MCMGR_USED */

    if (xTaskCreate(rpmsg_task, "rpmsg_task", RPMSG_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &rpmsg_task_handle) != pdPASS)
    {
        PRINTF("\r\nFailed to create rpmsg_rx_task\r\n");
        for (;;)
            ;
    }

    vTaskStartScheduler();

    PRINTF("Failed to start FreeRTOS on core0.\n");
    for (;;)
        ;
}

【问题讨论】:

    标签: c task structure freertos


    【解决方案1】:
    1. 你过度使用volatile。此代码中不需要您的任何volatiles。
    2. 您的pmsg_task 在创建rpmsg_tx_task 后通过返回退出。这很糟糕,有两个原因。您将对本地的引用传递给其他任务,然后退出该函数。这是未定义的行为。第二个原因是 - 你不能以这种方式终止任务。如果删除当前任务,则需要使用任务句柄或 NULL 调用 vTaskDelete 函数。
    3. 在使用 RTOS 对嵌入式目标进行编程之前,您需要学习一点 C 语言 - 尤其是指针、类型、强制转换、作用域等。它需要非常好的C语言知识。 您正在尝试取消引用 void * 指针。这种指针没有任何类型信息。即使您将指针传递给 struct 它仍然不引用任何类型。您需要转换或使用 temp 变量。
    struct rpmsg_struct *paramstruct = param;
    paramstruct -> ...
    

    ((struct rpmsg_struct *)param) -> ....
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 2010-10-26
      • 2015-12-02
      • 1970-01-01
      • 2014-08-03
      • 1970-01-01
      相关资源
      最近更新 更多