This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM625: SystemP_WAIT_FOREVER 是 延时程序吗?

Part Number: AM625

void ipc_rpmsg_echo_remote_core_start()
{
int32_t status;
RPMessage_CreateParams createParams;
// char recvMsg[MAX_MSG_SIZE];
uint16_t recvMsgSize, remoteCoreId;
uint32_t remoteCoreEndPt;
uint32_t msgCount = 0u;

RPMessage_CreateParams_init(&createParams);
createParams.localEndPt = gRemoteServiceEndPt;
status = RPMessage_construct(&gRecvMsgObject, &createParams);
DebugP_assert(status==SystemP_SUCCESS);

#if defined(PDK_DM_R5_TEST)
status = RPMessage_announce(CSL_CORE_ID_R5FSS0_0, gRemoteServiceEndPt, "ti.ipc4.ping-pong");
DebugP_assert(status==SystemP_SUCCESS);
#else
/* wait for all cores to be ready */
IpcNotify_syncAll(SystemP_WAIT_FOREVER);
#endif

DebugP_log("[IPC RPMSG ECHO] Remote Core waiting for messages from main core ... !!!\r\n");

/* wait for messages forever in a loop */
while(1)
{
/* set 'recvMsgSize' to size of recv buffer,
* after return `recvMsgSize` contains actual size of valid data in recv buffer
*/
recvMsgSize = sizeof(recvMsg);
status = RPMessage_recv(&gRecvMsgObject,
recvMsg, &recvMsgSize,
&remoteCoreId, &remoteCoreEndPt,
SystemP_WAIT_FOREVER);
DebugP_assert(status==SystemP_SUCCESS);
/* echo the same message string as reply */

/* send ack to sender CPU at the sender end point */
status = RPMessage_send(
trmitMsg, recvMsgSize,
remoteCoreId, remoteCoreEndPt,
RPMessage_getLocalEndPt(&gRecvMsgObject),
SystemP_WAIT_FOREVER);
DebugP_assert(status==SystemP_SUCCESS);
msgCount++;

if (msgCount >= gMsgEchoCount)
{
break;
}
}

DebugP_log("[IPC RPMSG ECHO] Received and echoed %d messages ... !!!\r\n", gMsgEchoCount);
DebugP_log("All tests have passed!!\r\n");
/* This loop will never exit */
}

M4 在等待接收数据和等待发送数据时可以执行用户程序吗? 怎么实现?

  • M4核心在执行无限循环,等待接收消息并回应消息的过程中,看起来没有直接执行用户程序的余地,因为它被阻塞在 `RPMessage_recv` 调用中直到收到消息。

    方法有:

    1. 多线程或任务调度
    你可以将消息接收和处理部分放在一个线程中,而用户程序则在另一个线程中运行,实现并发执行。

    void ipc_rpmsg_echo_remote_task(void *arg) {
    // 上面提到的等待消息和回应消息的代码
    }
    
    void user_program_task(void *arg) {
    // 用户程序代码
    }
    
    int main(void) {
    // 创建两个任务:一个用于IPC通信,另一个用于用户程序
    Task_create(ipc_rpmsg_echo_remote_task, &taskParams, NULL);
    Task_create(user_program_task, &taskParams, NULL);
    
    // 启动RTOS任务调度器
    BIOS_start();
    }



    2. 或者用中断

    void messageReceivedISR(void) {
    // 检查并处理接收到的消息
    }
    
    int main(void) {
    // 配置中断来处理接收到的消息
    Interrupt_register(INT_MESSAGE_RECEIVED, messageReceivedISR);
    
    while(1) {
    // 在此执行用户程序代码
    }
    }

  • ../ipc_rpmsg_echo.c:274:24: error: use of undeclared identifier 'INT_MESSAGE_RECEIVED'
    Interrupt_register(INT_MESSAGE_RECEIVED, messageReceivedISR);                    设置中断有错误,怎么修改?

    void messageReceivedISR(void) {
    // 检查并处理接收到的消息
    recvMsgSize = sizeof(recvMsg);
    status = RPMessage_recv(&gRecvMsgObject,
    recvMsg, &recvMsgSize,
    &remoteCoreId, &remoteCoreEndPt,
    SystemP_WAIT_FOREVER);

    /* echo the same message string as reply */

    /* send ack to sender CPU at the sender end point */
    status = RPMessage_send(
    trmitMsg, recvMsgSize,
    remoteCoreId, remoteCoreEndPt,
    RPMessage_getLocalEndPt(&gRecvMsgObject),
    SystemP_WAIT_FOREVER);

    }

    messageReceivedISR    CCS 会把地址放到中断向量表中吗?

    RPMessage_recv函数 RPMessage_send函数有没有非阻塞的函数调用?

  • 关于设置中断的错误

    错误信息提示 `INT_MESSAGE_RECEIVED` 未声明。这意味着你试图使用一个未定义的中断号

    关于中断服务程序(ISR)的注册

    一旦你有了正确的中断号,就可以使用它来注册ISR。但请注意,直接在ISR中调用阻塞的 `RPMessage_recv` 和 `RPMessage_send` 函数可能不是一个好主意,因为这会阻塞ISR,从而可能影响系统的响应时间。理想情况下,ISR应该尽可能快地执行,并使用某种形式的通知机制(如信号量、消息队列或事件标志)来告知一个任务或线程来处理数据。

    关于非阻塞调用

    至于 `RPMessage_recv` 和 `RPMessage_send` 函数是否有非阻塞的版本,这取决于你使用的IPC库。IPC框架提供了非阻塞版本的API,或者允许你指定一个非阻塞模式的参数

    如果框架不直接支持非阻塞消息接收,你可以:

    使用轮询机制,在主循环中定期检查消息,同时执行其他任务。
    设计和实现一个基于中断的通知机制,中断服务例程仅用于标记消息的到达,并通过信号量、事件或其他同步机制通知主任务或处理线程。

  • /* Task priority, stack, stack size and task objects, these MUST be global's */
    #define IPC_RPMESSAGE_TASK_PRI (8U)
    #define LPM_MCU_UART_WAKEUP_TASK_PRI (8U)
    #define IPC_USER_PROGRAM_TASK_PRI (8U)

    #if defined (SOC_AM62AX)
    #define IPC_RPMESSAGE_TASK_STACK_SIZE (32*1024U)
    #else
    #define IPC_RPMESSAGE_TASK_STACK_SIZE (8*1024U)
    #endif
    #define IPC_USER_PROGRAM_TASK_STACK_SIZE (8*1024U)
    #define LPM_MCU_UART_WAKEUP_TASK_STACK_SIZE (1024U)

    uint8_t gIpcTaskStack[IPC_RPMESSAGE_NUM_RECV_TASKS][IPC_RPMESSAGE_TASK_STACK_SIZE] __attribute__((aligned(32)));
    TaskP_Object gIpcTask[IPC_RPMESSAGE_NUM_RECV_TASKS];

    uint8_t gLpmUartWakeupTaskStack[LPM_MCU_UART_WAKEUP_TASK_STACK_SIZE] __attribute__((aligned(32)));
    TaskP_Object gLpmUartWakeupTask;

    uint8_t ipcuserprogramTaskStack[IPC_USER_PROGRAM_TASK_STACK_SIZE] __attribute__((aligned(32)));
    TaskP_Object ipcuserprogramTask;

    void USER_PROGRAM_task(void *arg) {
    // 用户程序代码


    }

    void ipc_rpmsg_create_user_program_task()
    {
    int32_t status;
    TaskP_Params taskParams;


    TaskP_Params_init(&taskParams);
    taskParams.name = "USER_PROGRAM";
    taskParams.stackSize = IPC_USER_PROGRAM_TASK_STACK_SIZE;
    taskParams.stack = ipcuserprogramTaskStack;
    taskParams.priority = IPC_USER_PROGRAM_TASK_PRI;
    taskParams.taskMain = USER_PROGRAM_task;

    status = TaskP_construct(&ipcuserprogramTask, &taskParams);
    DebugP_assert(status == SystemP_SUCCESS);

    }

    改用 free RTOS,上面改写程序,编译出错

    Finished building: "../ipc_rpmsg_echo.c"

    Building target: "ipc_rpmsg_echo_linux_am62x-sk_m4fss0-0_freertos_ti-arm-clang.out"
    Invoking: Arm Linker
    "C:/ti/ccs1260/ccs/tools/compiler/ti-cgt-armllvm_3.2.1.LTS/bin/tiarmclang.exe" -mcpu=cortex-m4 -mfloat-abi=hard -mlittle-endian -mthumb -DSOC_AM62X -D_DEBUG_=1 -g -Wall -Wno-gnu-variable-sized-type-not-at-end -Wno-unused-function -Wl,-m"ipc_rpmsg_echo_linux.Debug.map" -Wl,-i"C:/ti/mcu_plus_sdk_am62x_09_01_00_39/source/kernel/freertos/lib" -Wl,-i"C:/ti/mcu_plus_sdk_am62x_09_01_00_39/source/drivers/lib" -Wl,-i"C:/ti/mcu_plus_sdk_am62x_09_01_00_39/source/board/lib" -Wl,-i"C:/ti/ccs1260/ccs/tools/compiler/ti-cgt-armllvm_3.2.1.LTS/lib" -Wl,--reread_libs -Wl,--diag_wrap=off -Wl,--display_error_number -Wl,--warn_sections -Wl,--xml_link_info="ipc_rpmsg_echo_linux_am62x-sk_m4fss0-0_freertos_ti-arm-clang_linkInfo.xml" -Wl,--ram_model -o "ipc_rpmsg_echo_linux_am62x-sk_m4fss0-0_freertos_ti-arm-clang.out" "./syscfg/ti_dpl_config.o" "./syscfg/ti_drivers_config.o" "./syscfg/ti_drivers_open_close.o" "./syscfg/ti_pinmux_config.o" "./syscfg/ti_power_clock_config.o" "./syscfg/ti_board_config.o" "./syscfg/ti_board_open_close.o" "./ipc_rpmsg_echo.o" "./main.o" "../linker.cmd" -Wl,-lfreertos.am62x.m4f.ti-arm-clang.debug.lib -Wl,-ldrivers.am62x.m4f.ti-arm-clang.debug.lib -Wl,-lboard.am62x.m4f.ti-arm-clang.debug.lib -Wl,-llibc.a -Wl,-llibsysbm.a
    makefile:147: recipe for target 'ipc_rpmsg_echo_linux_am62x-sk_m4fss0-0_freertos_ti-arm-clang.out' failed
    "../linker.cmd", line 29: error #10099-D: program will not fit into available memory, or the section contains a call site that requires a trampoline that can't be generated for this section. placement with alignment fails for section ".data" size 0x3f5. Available memory ranges:
    M4F_DRAM size: 0x10000 unused: 0xa8 max hole: 0xa8
    error #10010: errors encountered during linking; "ipc_rpmsg_echo_linux_am62x-sk_m4fss0-0_freertos_ti-arm-clang.out" not built
    tiarmclang: error: tiarmlnk command failed with exit code 1 (use -v to see invocation)
    gmake[1]: *** [ipc_rpmsg_echo_linux_am62x-sk_m4fss0-0_freertos_ti-arm-clang.out] Error 1
    makefile:143: recipe for target 'all' failed
    gmake: *** [all] Error 2

    **** Build Finished ****

    哪里出了问题?

  • #define IPC_USER_PROGRAM_TASK_STACK_SIZE (8*1024U)  改小 4*1024 编译通过