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.

AM5749: Debouncing PRU input

Part Number: AM5749
Other Parts Discussed in Thread: TLV320AIC3104EVM-K, AM5728

On the AM5749 I have performed pin muxing to change pin vin1a_d6 to pr1_pru0_gpi3 (attaches to external push button), and gpio4_8 to pr1_pru1_gpo4 (attaches to external LED). Using a combination of code from the TI trainings I have set up a scenario that will turn the LED on and off when the button is pushed. RPMsg is also enabled and sends a message to the device driver saying whether the button is pushed or released.

Currently I debounce with using a large delay [__delay_cycles(100000000)]. The problem with this is that the response time is too slow for my desired functionality however, reducing the delay time causes the remoteproc to either completely freeze and require a restart or loses all functionality and doesn’t register the button push at all.

I am new to embedded systems and PRU, and am unsure if this is a PRU/RPMsg problem or a debouncing issue. I have tried different types of debouncing methods and it doesn’t improve the situation. Is there a specific method to debounce PRU inputs or is there any advice to improving the speed of my input/output response.

I have also seen issues with using __delay_cycles causing strange outputs, I am looking into using IEP to act as a timer for debouncing to avoid using __delay_cylces but so far am not having a great amount of luck.

Any suggestions would be greatly appreciated. 

  • Hello Tay,

    I have a couple of questions to get started:

    Could you please share with me what SDK version/s you are using?

    What TI evm are you using or is this a custom board?

    -Josue

  • Hello,

    I am using the TI-processor-sdk-linux-am57xx-evm-08_02_01_00 processor on the TLV320AIC3104EVM-K board.

  • Tay,

    Can you let me know which AM57 board you are using?

    Could you also let me know which examples you are looking at?

    -Josue

  • Hi,

    Sorry about that, the board is the AM572x EVM, and my chip is actually the AM5728.

    I have been using the examples from the PRU Hands on Labs, specifically Lab 2 (Read Push Button Switch and Toggle LED) and Lab 5 (RPMsg communication between ARM and PRU - RPMsg_PRU_Echo_Interrupt1_1) combined with the PRU_IEP example in the am335x folder - adjusted to match the AM57x PRU_IEP.h.

    Thanks

  • Hello Tay,

    Please allow for some time to look at your issue since these Labs were not validated on AM57. 

    -Josue

  • Hello Tay,

    I will be jumping in to help a bit here.

    First, please note that the PRU cores are NOT multithreaded - it only works on one task at a time. That means that __delay_cycles will cause the PRU cores to do nothing for that number of PRU clock cycles (100,000,000 clock cycles if the core is running at 200MHz means the core is doing nothing for 500ms). So if you want the PRU to do something else, and then occasionally poll to see if the counter has gone off, I would suggest using the IEP timer instead.

    Another tool you could look into is the PRU_CYCLE register:

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1122963/am3358-how-to-use-scratch-pad-to-exchange-pru0-and-pru1/4166588#4166588

    (e.g., when a low signal is detected, check the PRU_CYCLE register. If the cycle register says it has been XXX or more cycles since the last low signal, then reset the cycle register to 0, and send an RPMsg. If the cycle register is less than XXX cycles, do nothing because you assume you are in your debounce window)

    You can find an example of programming the IEP timer from the PRU in the PRU Software Support Package (PSSP) here:
    https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/examples/am335x/PRU_IEP

    When I ran tests on AM335x Linux / PRU RPMsg echo example, it took about 1ms on average for an RPMsg to travel round trip from Linux, to PRU, back to Linux. I would expect AM57x average round trip latency to be better, since the Linux cores are more powerful.

    Is there a specific part of the code that is not working? i.e., the LEDs light up as expected, but the RPMsg messages are not going through as expected?

    Regards,

    Nick

  • Hi Nick,

    Thank you for responding. I am trying to use the IEP timer combined with RPMsg but am struggling as the RPMsg device file doesn't get created when I start the remote proc. For reference I will attach the code I am working with, I load a separate file onto remoteproc4 that initialises an interrupt on R31 for an external switch and then on remoteproc5 I have the attached code echoed onto it.

    I wish for the interrupt from the switch to be detected during polling and then wait a small debounce period (using the IEP timer) before confirming the switch state. Depending on the switch state an RPMsg is to be sent to update the user. 

    I have compiled this .c file with unedited intc_map_1.h, resource_table.h and AM57xx_PRU_intc_rscTbl.cmd files [attached]. I am wondering if any of these need to be edited or if my error is in my main.c code? 

    main.c

     

    #include <stdint.h>
    #include <stdio.h>
    #include <stdbool.h>
    #include <string.h>
    #include <pru_cfg.h>
    #include <pru_intc.h>
    #include <rsc_types.h>
    #include <pru_rpmsg.h>
    #include <pru_iep.h>
    #include "resource_table.h"
    #include "intc_map_1.h"
    
    volatile register uint32_t __R30;
    volatile register uint32_t __R31;
    
    #define HOST1_MASK 	(0x80000000)
    #define LED_ON 		(__R30 |= (1 << 4))
    #define LED_OFF 	(__R30 &= ~(1 << 4))
    
    /*RPMsg variables*/
    #define TO_ARM_HOST			18
    #define FROM_ARM_HOST		19
    
    #define CHAN_NAME			"rpmsg-pru"
    #define CHAN_PORT			31
    #define CHAN_DESC			"Channel 31"
    
    #define VIRTIO_CONFIG_S_DRIVER_OK	4
    bool RPMessage=true;
    
    struct pru_rpmsg_transport transport;
    uint16_t src=1024, dst=31;
    volatile uint8_t *status;
    
    void iep_timer_config(uint32_t comp_val)
    {	
    	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
    	
    	/* Disable counter */
    	CT_IEP.GLB_CFG_bit.CNT_ENABLE = 0;
    	
    	/* Reset Count register */
    	CT_IEP.LOW_COUNTER_bit.COUNT = 0x00000000;
    	CT_IEP.HIGH_COUNTER_bit.COUNT = 0x00000000;
    	
    	/* Clear overflow status register*/
    	CT_IEP.GLB_STS_bit.CNT_OVF = 0x01;  
    	
    	/* Set compare0 value */
    	CT_IEP.CMP0_0_bit.CMP = (comp_val * 200); 
    	
    	/* Clear compare status */
    	CT_IEP.CMP_STS = 0xFFFFFFFF;
    	
    	/* Disable compensation */
    	CT_IEP.COMPEN_bit.COMPEN_CNT = 0x0; 
    	
    	/* Enable timer reset on compare equal */
    	CT_IEP.CMP_CFG_bit.CMP0_RST_CNT_EN = 0x1;
    	
    	/* Enable comparison for CMP0*/
    	CT_IEP.CMP_CFG_bit.CMP_EN= 0x1;
    	
    	/* Configure incr value */
    	CT_IEP.GLB_CFG_bit.DEFAULT_INC = 0x1;
    	
    	/* Clear the status of all interrupts */
    	CT_INTC.SECR0 = 0xFFFFFFFF;
    	CT_INTC.SECR1 = 0xFFFFFFFF;
    	CT_IEP.GLB_CFG_bit.CNT_ENABLE = 0x1;
    	
    	/* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */
    	CT_INTC.SICR_bit.STATUS_CLR_INDEX = FROM_ARM_HOST;
    	
    	/*Enable timer*/ 
    	CT_IEP.GLB_CFG = 0x11;	
    }	
    
    void intc_config(void)
    {
    	__R30 = 0x00000000;
    	/* Set event 7 to channel 1 */
    	CT_INTC.CMR1_bit.CH_MAP_7 = 1;
    	CT_INTC.HMR0_bit.HINT_MAP_1 = 1;
    	/* Ensure event 7 is cleared*/
    	CT_INTC.SICR = 7;
    	/* Enable system event (7th bit = sys interrupt 7) */
    	CT_INTC.ESR0 = 0x80;
    	/* Enable host interrupt 1 */
    	CT_INTC.HIEISR |= (1 << 0);
    	/* Globally enable interrupts */
    	CT_INTC.GER = 1;
    
    }
    
    uint8_t pushbutton (void)
    {
    	/* Initialise RPMsg messages depending on switch state*/
    	char switch_press[20];
    	uint16_t closed_len = 9;
    	memcpy(switch_press, "LED on \n", closed_len);
    
    	char switch_release[20];
    	uint16_t open_len = 10;
    	memcpy(switch_release, "LED off \n", open_len);
    
    	/* Initialise debounce variables */
    	static uint32_t prev_button_status = 0;  
    	static uint32_t debounceTime = 0;
    
    
    	/* Poll until R31.31 is set */
    	if (__R31 & HOST1_MASK) 
    	{ 
    		/* Check if timer interrupt */
    		if (CT_INTC.SECR0 & (1 << 7)) 
    		{
    			/* Read the current button status */ 
    			uint32_t current_button_status = (__R31 & HOST1_MASK) ? 1 : 0;
    
    			CT_IEP.CMP_STS = 1;			/*clear compare status*/ 
    			__delay_cycles(2);
    			CT_INTC.SECR0 = 0x80;			/*clear event signal*/ 	
    			CT_INTC.SICR_bit.STATUS_CLR_INDEX = 7;
    
    			// Check if the button state has changed
    			if (current_button_status != prev_button_status) 
    			{
    				debounceTime = 0; // Reset debounce timer
    			} else 
    			{
    				debounceTime += 10; // 10ms has passed
    			}
    
    			/*Check to see if status remains same after 50ms time interval*/
    			if (debounceTime >= 50) 
    			{
    					if (current_button_status == 0)
    					{
    						/*Send RPMsg that LED is off and turn LED off*/
    						pru_rpmsg_send(&transport, dst, src, switch_press, closed_len);	
    						LED_OFF;
    						/*flag that a message has been sent*/
    						RPMessage = true;
    					}
    					else
    					{	
    						/*Send message that switch is closed, LED will turn on*/
    						if(!RPMessage)
    						{
    							/*Send message that LED on and turn LED on*/
    							pru_rpmsg_send(&transport, dst, src, switch_release, open_len);
    							LED_OFF;
    
    							/*Flag that message has been sent*/
    							RPMessage=true;
    						}
    						else
    						{
    							RPMessage=false;
    						}
    
    					}
    				/*Update button status*/
    				prev_button_status = current_button_status;
    				debounceTime = 0;
    				
    			}
    			
    		}
    	}
    }
    
    
    void cleanup(void)
    {
    	/*Clear interrupts from switch and RPMsg*/
    	CT_INTC.SICR = 16; 
    	CT_INTC.SICR_bit.STATUS_CLR_INDEX = FROM_ARM_HOST;	
    }
    
    void main(void)
    {
    	//intc_config();
    
    	/* Initialise RPMsg */
    	/* Make sure the Linux drivers are ready for RPMsg communication */
    	status = &resourceTable.rpmsg_vdev.status;
    	
    	while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK));
    
    	/* Initialize the RPMsg transport structure */
    	pru_rpmsg_init(&transport, &resourceTable.rpmsg_vring0, &resourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST);
    	
    	/* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */
    	while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_PORT) != PRU_RPMSG_SUCCESS);
    	
    	iep_timer_config(50); /* 10 ms*/
    
    	while (1) 
    	{	
    		pushbutton();
    		cleanup();
    	}
    }

    resource_table.h

    /*
     * Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     *	* Redistributions of source code must retain the above copyright
     *	  notice, this list of conditions and the following disclaimer.
     *
     *	* Redistributions in binary form must reproduce the above copyright
     *	  notice, this list of conditions and the following disclaimer in the
     *	  documentation and/or other materials provided with the
     *	  distribution.
     *
     *	* Neither the name of Texas Instruments Incorporated nor the names of
     *	  its contributors may be used to endorse or promote products derived
     *	  from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #ifndef _RESOURCE_TABLE_H_
    #define _RESOURCE_TABLE_H_
    
    #include <stddef.h>
    #include <rsc_types.h>
    #include "pru_virtio_ids.h"
    
    /*
     * Sizes of the virtqueues (expressed in number of buffers supported,
     * and must be power of 2)
     */
    #define PRU_RPMSG_VQ0_SIZE	16
    #define PRU_RPMSG_VQ1_SIZE	16
    
    /*
     * The feature bitmap for virtio rpmsg
     */
    #define VIRTIO_RPMSG_F_NS	0		//name service notifications
    
    /* This firmware supports name service notifications as one of its features */
    #define RPMSG_PRU_C0_FEATURES	(1 << VIRTIO_RPMSG_F_NS)
    
    /* Definition for unused interrupts */
    #define HOST_UNUSED		255
    
    struct my_resource_table {
    	struct resource_table base;
    
    	uint32_t offset[1]; /* Should match 'num' in actual definition */
    
    	/* rpmsg vdev entry */
    	struct fw_rsc_vdev rpmsg_vdev;
    	struct fw_rsc_vdev_vring rpmsg_vring0;
    	struct fw_rsc_vdev_vring rpmsg_vring1;
    };
    
    #pragma DATA_SECTION(resourceTable, ".resource_table")
    #pragma RETAIN(resourceTable)
    struct my_resource_table resourceTable = {
    	1,	/* Resource table version: only version 1 is supported by the current driver */
    	1,	/* number of entries in the table */
    	0, 0,	/* reserved, must be zero */
    	/* offsets to entries */
    	{
    		offsetof(struct my_resource_table, rpmsg_vdev),
    	},
    
    	/* rpmsg vdev entry */
    	{
    		(uint32_t)TYPE_VDEV,                    //type
    		(uint32_t)VIRTIO_ID_RPMSG,              //id
    		(uint32_t)0,                            //notifyid
    		(uint32_t)RPMSG_PRU_C0_FEATURES,	//dfeatures
    		(uint32_t)0,                            //gfeatures
    		(uint32_t)0,                            //config_len
    		(uint8_t)0,                             //status
    		(uint8_t)2,                             //num_of_vrings, only two is supported
    		{ (uint8_t)0, (uint8_t)0 },             //reserved
    		/* no config data */
    	},
    	/* the two vrings */
    	{
    		FW_RSC_ADDR_ANY,        //da, will be populated by host, can't pass it in
    		16,                     //align (bytes),
    		PRU_RPMSG_VQ0_SIZE,     //num of descriptors
    		0,                      //notifyid, will be populated, can't pass right now
    		0                       //reserved
    	},
    	{
    		FW_RSC_ADDR_ANY,        //da, will be populated by host, can't pass it in
    		16,                     //align (bytes),
    		PRU_RPMSG_VQ1_SIZE,     //num of descriptors
    		0,                      //notifyid, will be populated, can't pass right now
    		0                       //reserved
    	},
    };
    
    #endif /* _RESOURCE_TABLE_H_ */
    

    intc_map_1.h

    /*
     * Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
     *
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     *      * Redistributions of source code must retain the above copyright
     *        notice, this list of conditions and the following disclaimer.
     *
     *      * Redistributions in binary form must reproduce the above copyright
     *        notice, this list of conditions and the following disclaimer in the
     *        documentation and/or other materials provided with the
     *        distribution.
     *
     *      * Neither the name of Texas Instruments Incorporated nor the names of
     *        its contributors may be used to endorse or promote products derived
     *        from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #ifndef _INTC_MAP_1_H_
    #define _INTC_MAP_1_H_
    
    /*
     * ======== PRU INTC Map ========
     *
     * Define the INTC mapping for interrupts going to the ICSS / ICSSG:
     * 	ICSS Host interrupts 0, 1
     * 	ICSSG Host interrupts 0, 1, 10-19
     *
     * Note that INTC interrupts going to the ARM Linux host should not be defined
     * in this file (ICSS/ICSSG Host interrupts 2-9).
     *
     * The INTC configuration for interrupts going to the ARM host should be defined
     * in the device tree node of the client driver, "interrupts" property.
     * See Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
     * entry #interrupt-cells for more.
     *
     * For example, on ICSSG:
     *
     * &client_driver0 {
     * 	interrupt-parent = <&icssg0_intc>;
     * 	interrupts = <21 2 2>, <22 3 3>;
     * 	interrupt-names = "interrupt_name1", "interrupt_name2";
     * };+ / 
     * 
     *
     */
    
    #include <stddef.h>
    #include <rsc_types.h>
    
    /*
     * .pru_irq_map is used by the RemoteProc driver during initialization. However,
     * the map is NOT used by the PRU firmware. That means DATA_SECTION and RETAIN
     * are required to prevent the PRU compiler from optimizing out .pru_irq_map.
     */
    #pragma DATA_SECTION(my_irq_rsc, ".pru_irq_map")
    #pragma RETAIN(my_irq_rsc)
    
    struct pru_irq_rsc my_irq_rsc  = {
    	0,			/* type = 0 */
    	1,			/* number of system events being mapped */
    	{
    		{19, 1, 1},
    	},
    };
    
    #endif /* _INTC_MAP_1_H_ */

     AM57xx_PRU_intc_rscTbl.cmd

    /****************************************************************************/
    /*  AM57xx_PRU.cmd                                                          */
    /*  Copyright (c) 2015-2021  Texas Instruments Incorporated                 */
    /*                                                                          */
    /*    Description: This file is a linker command file that can be used for  */
    /*                 linking PRU programs built with the C compiler and       */
    /*                 the resulting .out file on an AM57xx device.             */
    /****************************************************************************/
    
    -cr								/* Link using C conventions */
    
    /* Specify the System Memory Map */
    MEMORY
    {
          PAGE 0:
    	PRU_IMEM		: org = 0x00000000 len = 0x00003000  /* 12kB PRU-ICSS1 Instruction RAM */
    
          PAGE 1:
    
    	/* RAM */
    
    	PRU_DMEM_0_1	: org = 0x00000000 len = 0x00002000 CREGISTER=24 /* 8kB PRU Data RAM 0_1 */
    	PRU_DMEM_1_0	: org = 0x00002000 len = 0x00002000	CREGISTER=25 /* 8kB PRU Data RAM 1_0 */
    
    	  PAGE 2:
    	PRU_SHAREDMEM	: org = 0x00010000 len = 0x00008000 CREGISTER=28 /* 32kB Shared RAM */
    
    	DDR			    : org = 0x80000000 len = 0x00010000	CREGISTER=31
    	L3OCMC			: org = 0x40000000 len = 0x00010000	CREGISTER=30
    
    
    	/* Peripherals */
    
    	PRU_CFG			: org = 0x00026000 len = 0x00000120	CREGISTER=4
    	PRU_ECAP		: org = 0x00030000 len = 0x00000060	CREGISTER=3
    	PRU_IEP			: org = 0x0002E000 len = 0x0000031C	CREGISTER=26
    	PRU_INTC		: org = 0x00020000 len = 0x00001504	CREGISTER=0
    	PRU_UART		: org = 0x00028000 len = 0x00000038	CREGISTER=7
    
    	MCASP3_DMA		: org = 0x46000000 len = 0x00000100	CREGISTER=8
    	I2C3			: org = 0x48060000 len = 0x00000300	CREGISTER=5
    
    	RSVD1			: org = 0x48040000 len = 0x0000005C	CREGISTER=1
    	RSVD2			: org = 0x4802A000 len = 0x000000D8	CREGISTER=2
    	RSVD6			: org = 0x48030000 len = 0x000001A4	CREGISTER=6
    	RSVD9			: org = 0x4A100000 len = 0x0000128C	CREGISTER=9
    	RSVD10			: org = 0x48318000 len = 0x00000100	CREGISTER=10
    	RSVD11			: org = 0x48022000 len = 0x00000088	CREGISTER=11
    	RSVD12			: org = 0x48024000 len = 0x00000088	CREGISTER=12
    	RSVD13			: org = 0x48310000 len = 0x00000100	CREGISTER=13
    	RSVD14			: org = 0x481CC000 len = 0x000001E8	CREGISTER=14
    	RSVD15			: org = 0x481D0000 len = 0x000001E8	CREGISTER=15
    	RSVD16			: org = 0x481A0000 len = 0x000001A4	CREGISTER=16
    	RSVD17			: org = 0x4819C000 len = 0x000000D8	CREGISTER=17
    	RSVD18			: org = 0x48300000 len = 0x000002C4	CREGISTER=18
    	RSVD19			: org = 0x48302000 len = 0x000002C4	CREGISTER=19
    	RSVD20			: org = 0x48304000 len = 0x000002C4	CREGISTER=20
    	RSVD21			: org = 0x00032400 len = 0x00000100	CREGISTER=21
    	RSVD22			: org = 0x480C8000 len = 0x00000140	CREGISTER=22
    	RSVD23			: org = 0x480CA000 len = 0x00000880	CREGISTER=23
    	RSVD27			: org = 0x00032000 len = 0x00000100	CREGISTER=27
    	RSVD29			: org = 0x49000000 len = 0x00001098	CREGISTER=29
    }
    
    /* Specify the sections allocation into memory */
    SECTIONS {
    	/* Forces _c_int00 to the start of PRU IRAM. Not necessary when loading
    	   an ELF file, but useful when loading a binary */
    	.text:_c_int00*	>  0x0, PAGE 0
    
    	.text		>  PRU_IMEM, PAGE 0
    	.stack		>  PRU_DMEM_0_1, PAGE 1
    	.bss		>  PRU_DMEM_0_1, PAGE 1
    	.cio		>  PRU_DMEM_0_1, PAGE 1
    	.data		>  PRU_DMEM_0_1, PAGE 1
    	.switch		>  PRU_DMEM_0_1, PAGE 1
    	.sysmem		>  PRU_DMEM_0_1, PAGE 1
    	.cinit		>  PRU_DMEM_0_1, PAGE 1
    	.rodata		>  PRU_DMEM_0_1, PAGE 1
    	.rofardata	>  PRU_DMEM_0_1, PAGE 1
    	.farbss		>  PRU_DMEM_0_1, PAGE 1
    	.fardata	>  PRU_DMEM_0_1, PAGE 1
    
    	.resource_table > PRU_DMEM_0_1, PAGE 1
    
    	.pru_irq_map (COPY) :
    	{
    		*(.pru_irq_map)
    	}
    }
    

  • Hello Tay,

    It looks like you are using the right version of the PSSP (for Linux kernel 5.10, you want to use PSSP v6.0.0 - v6.1.0:  https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package ). No time for me to read through the code today, apologies.

    Getting a "known good state" to start from

    Can you please start by confirming that you can get the out-of-the-box RPMsg_echo example running? You can use lab 5, or just the example here:
    https://git.ti.com/cgit/pru-software-support-package/pru-software-support-package/tree/examples/am572x?h=v6.1.0

    Another good resource for getting started is our new PRU Getting Started Labs. I'll send you the link for the latest AM62x docs, but the PRU Getting Started Labs apply to AM57x: https://software-dl.ti.com/processor-sdk-linux/esd/AM62X/09_00_00_03/exports/docs/common/PRU-ICSS/PRU-Getting-Started-Labs.html

    Next steps 

    Once you have that known good state, you can start adding code bit by bit, using the debug methods in the PRU Getting Started Labs Lab 5, until you figure out the thing that was causing problems.

    I'm handing your thread back to Josue for followup discussions as needed.

    Regards,

    Nick