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.

Question regarding interrupt processing time

Hi,

I am using SYS/BIOS and NDK.

My program is too slow to process interrupt and some tasks. The program is running using CCS.

Active build is Release and I disconnected CCS from EVM6678l to accelerate program execution.

I want to explain my code and attach my main program and *.cfg file.

My project is not final and is for SYS/BIOS and NDK test.

I have two interrupt, UART and GPIO. UART is to get keyboard input and GPIO interrupt occurs every 12.5 us.

Right now in every 12.5us, GPIO interrupt post Swi. Swi just toggles LED.

Also I am using clock in every 1second period. When I tested interrupts, I am not using any kind of IP connection.

When I power on EVM, load *.out and run the code, clock task is working well because I didn't provide GPIO interrupt to EVM6678l.

When GPIO interrupts were given to EVM board, LED toggle is not working well. I think most of DSP performance is consumed by GPIO interrupt processing.

I think DSP is working very slowly.

Even when I was pressing keyboard for UART interrupt, DSP crashed within 50 characters. continuos UART interrupt caused DSP to crash.

Right now, I think there are two possibilities.

1) Using CCS makes DSP to work at lower speed because there are many message communications between CCS and DSP.

    But "disconnect Target" doesn't accelerate DSP speed. EVM6678l clock is 1 GHz and it's very fast.

    How can I get best DSP performance? Sould I burn my code in NAND flash?

2) I think SYS/BIOS is too heavy to process may interrupt. Should I code interrupt routine not using SYS/BIOS like old style?

   

2844.nara_dsp.c
/*
 *  ======== main.c ========
 */

#include <xdc/std.h>

#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>

#include <ti/sysbios/BIOS.h>

#include <ti/sysbios/knl/Task.h>

// added ByPark
#include <stdlib.h>
#include <ctype.h>
#include <ti/ndk/inc/netmain.h>
#include <xdc/runtime/Memory.h>
#include <ti/sysbios/family/c64p/Hwi.h>
#include <ti/sysbios/knl/Swi.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/family/c66/tci66xx/CpIntc.h>
#include <ti/csl/csl_gpio.h>
#include <ti/csl/csl_gpioAux.h>
/* NIMU */
#include "ti/transport/ndk/nimu/nimu_eth.h"
#include "ti\platform\platform.h"
#include "ti\platform\resource_mgr.h"
#include "ti/csl/cslr_uart.h"
#include "ti\platform\evmc6678l\platform_lib\include\evmc66x_uart.h"
#include "ti\platform\evmc6678l\platform_lib\include\evmc66x_gpio.h"
//#define CSL_UART_REGS 0x02540000
#define hUartRegs ((CSL_UartRegs*)	CSL_UART_REGS)
#define GPIO_CFG_BASE				(0x02320000)
#define GPIO_REG_BINTEN				(0x8)
#define GPIO_REG_DIR				(0x10)
#define GPIO_REG_OUT_DATA			(0x14)
#define GPIO_REG_SET_DATA			(0x18)
#define GPIO_REG_CLR_DATA			(0x1C)
#define GPIO_REG_IN_DATA			(0x20)
#define GPIO_REG_SET_RIS_TRIG		(0x24)
#define GPIO_REG_CLR_RIS_TRIG		(0x28)
#define GPIO_REG_SET_FAL_TRIG		(0x2C)
#define GPIO_REG_CLR_FAL_TRIG		(0x30)
#define NOR_DEVICE					PLATFORM_DEVID_NORN25Q128;

unsigned int GPIO_INT_DONE = 0;

Void HWI_UART_Handler(UArg arg);
Void HWI_GPIO_Handler(UArg arg);
void SWI_UART_Handler();
void SWI_GPIO_Handler();
void TASK_UART_Handler();
void SPI_NOR_Read(/*int length*/);

extern Swi_Handle uartSwiHandle;
extern Swi_Handle gpioSwiHandle;
extern Semaphore_Handle uart_sem;

unsigned int Uart_Interrupt_Received_Flag = 0;
static char cmdString[30];
static unsigned int cmdStringPtr = NULL;

/* Platform Information - we will read it form the Platform Library */
platform_info  gPlatformInfo;

//---------------------------------------------------------------------------
// Title String
//
char *VerStr = "\nUDP/IP Stack 'NARA Controls Inc.' DSP Application\n\n";

// Our NETCTRL callback functions
static void   NetworkOpen();
static void   NetworkClose();
static void   NetworkIPAddr( IPN IPAddr, uint IfIdx, uint fAdd );

// Fun reporting function
static void   ServiceReport( uint Item, uint Status, uint Report, HANDLE hCfgEntry );

// External references
extern int  ConStrToIPN( char *str, IPN *pIPN );
extern int dtask_udp_hello();
extern int dtask_udp_send();

//---------------------------------------------------------------------------
// Configuration
//
char *HostName		= "tidsp";
char *LocalIPAddr	= "192.168.2.100";
char *LocalIPMask	= "255.255.255.0";    // Not used when using DHCP
char *GatewayIP		= "192.168.2.101";    // Not used when using DHCP
char *DomainName	= "demo.net";         // Not used when using DHCP
char *DNSServer		= "0.0.0.0";          // Used when set to anything but zero
// used for PC server
char *serverIPAddr	= "192.168.168.140";
short serverPort	= 7;

// Simulator EMAC Switch does not handle ALE_LEARN mode, so please configure the
// MAC address of the PC where you want to launch the webpages and initiate PING to NDK */

Uint8 clientMACAddress [6] = {0x5C, 0x26, 0x0A, 0x69, 0x44, 0x0B}; /* MAC address for my PC */
/*
 *  ======== main ========
 */
Void main()
{ 
	int i=0;

	// enable ERBI & ELSI of IER for UART
    CSL_FINS (hUartRegs->IER, UART_IER_ERBI,  CSL_UART_IER_ERBI_ENABLE);
    CSL_FINS (hUartRegs->IER, UART_IER_ELSI,  CSL_UART_IER_ELSI_ENABLE);
    // mapping system interrupt(148) to host interrupt(32)
    CpIntc_mapSysIntToHostInt(0,148,32);
    CpIntc_dispatchPlug(148, &HWI_UART_Handler,0, TRUE);
    CpIntc_enableHostInt(0,32);
    CpIntc_clearSysInt(0,148);

    //set GPIO_0 pin as an input
    *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_DIR) |= 0x1;
    //set falling edge to trigger GPIO_0 interrupt
    *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_SET_FAL_TRIG) |= 0x1;
    //clear rising edge trigger of GPIO_0 interrupt
    *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_SET_RIS_TRIG) &= 0xFFFFFFFE;
    //enable GPIO interrupts
    *(unsigned int*)(GPIO_CFG_BASE+GPIO_REG_BINTEN) |= 0x1;

    for(i=0;i<4;i++)
		platform_led(i, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);

    platform_write("\nStart BIOS 6\n");
	platform_write("NARA DSP Platform Started.\n");

	memset(cmdString, 0, sizeof(cmdString));
	cmdStringPtr = NULL;

    BIOS_start();		/* enable interrupts and start SYS/BIOS */
}

/*************************************************************************
* EVM_init()
* Initializes the platform hardware. This routine is configured to start in
* the evm.cfg configuration file. It is the first routine that BIOS
* calls and is executed before Main is called. If you are debugging within
* CCS the default option in your target configuration file may be to execute
* all code up until Main as the image loads. To debug this you should disable
* that option.
************************************************************************/
void EVM_init()
{
	platform_init_flags sFlags;
	platform_init_config sConfig;
	int32_t pform_status;
	/* Initialize the UART */
	platform_uart_init();
	platform_uart_set_baudrate(115200);
	(void) platform_write_configure(PLATFORM_WRITE_ALL);
	/*
	* You can choose what to initialize on the platform by setting the following
	* flags. Things like the DDR, PLL, etc should have been set by the boot loader.
	*/
	memset( (void *) &sFlags, 0, sizeof(platform_init_flags));
	memset( (void *) &sConfig, 0, sizeof(platform_init_config));
	sFlags.pll = 0;		/* PLLs for clocking */
	sFlags.ddr = 0;		/* External memory */
	sFlags.tcsl = 1;	/* Time stamp counter */
	sFlags.phy = 1;		/* Ethernet */
	sFlags.ecc = 0;		/* Memory ECC */
	sConfig.pllm = 0;	/* Use libraries default clock divisor */
	pform_status = platform_init(&sFlags, &sConfig);
	/* If we initialized the platform okay */
	if (pform_status != Platform_EOK)
	{
		/* Initialization of the platform failed... die */
		platform_write("Platform failed to initialize. Error code %d \n", pform_status);
		platform_write("We will die in an infinite loop... \n");
		while (1)
		{
			(void) platform_led(1, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
			(void) platform_delay(50000);
			(void) platform_led(1, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
			(void) platform_delay(50000);
		}
	}

	return;
}

Void HWI_UART_Handler(UArg arg)
{
//	static int LED0_state = 0;
//	uint8_t UART_Byte_Recv;

	Swi_post(uartSwiHandle);

//	CpIntc_clearSysInt(0,148);
//	UART_Byte_Recv=UartReadData();
//	if(LED0_state)
//		platform_led(0, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
//	else
//		platform_led(0, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
//	LED0_state ^= 1;
}

Void HWI_GPIO_Handler(UArg arg)
{
	Swi_post(gpioSwiHandle);
}

void SWI_UART_Handler()
{
	static int LED0_state = 0;

	Uart_Interrupt_Received_Flag = 1;

	CpIntc_clearSysInt(0,148);

	if(LED0_state)
		platform_led(0, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
	else
		platform_led(0, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
	LED0_state ^= 1;

	Semaphore_post(uart_sem);
}

void SWI_GPIO_Handler()
{
	static int LED2_state = 0;

	Uart_Interrupt_Received_Flag = 2;

	if(LED2_state)
		platform_led(2, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
	else
		platform_led(2, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
	LED2_state ^= 1;

//	Semaphore_post(uart_sem);
}

void CLK_LED_Handler(void)
{
	static int LED1_state = 0;

	if(LED1_state)
		platform_led(1, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
	else
		platform_led(1, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);

	LED1_state ^= 1;
}

void TASK_UART_Handler()
{
	uint8_t UART_Byte_Recv;
	unsigned int indata;
	IPN	IPTemp;

	while(1)
	{
		Semaphore_pend(uart_sem, BIOS_WAIT_FOREVER);

		switch(Uart_Interrupt_Received_Flag)
		{
		case 1:
			Uart_Interrupt_Received_Flag = 0;
			UART_Byte_Recv=UartReadData();
			if(UART_Byte_Recv==0xD) {
				platform_uart_write(0xA);
				platform_uart_write(UART_Byte_Recv);

				if(strncmp("NOR read", cmdString, 8)==0) {
					SPI_NOR_Read();
					platform_uart_write(0xA);	// LF
					platform_uart_write(0xD);	// CR
				}
				else if(strncmp("UDP send", cmdString, 8)==0) {
				       if(!ConStrToIPN(serverIPAddr,&IPTemp))
				           platform_write("Invalid address\n\n");
				       else
				    	   dtask_udp_send(IPTemp);
				}

				memset(cmdString, 0, sizeof(cmdString));
				cmdStringPtr = 0;
			}
			else {
				platform_uart_write(UART_Byte_Recv);
				if(UART_Byte_Recv!=0x8)
					cmdString[cmdStringPtr++] = UART_Byte_Recv;
				else {
					if(cmdStringPtr>0) {
						cmdStringPtr-=1;
						cmdString[cmdStringPtr] = NULL;
					}
				}
			}
			break;
		case 2:
			Uart_Interrupt_Received_Flag = 0;
			// read GPIO_0 status
			indata = gpioReadInput(GPIO_0);
			if(indata)
				platform_write("\nGPIO(0) high\n");
			else
				platform_write("\nGPIO(0) low\n");
			break;
		default:
			break;
		}
	}

}

void SPI_NOR_Read(/*int length*/)
{
	int32_t					block, page;
	uint32_t				deviceid;
//	uint32_t				flash_selection = NULL;
	uint32_t				offset;
	uint8_t					*buffer = NULL;
	PLATFORM_DEVICE_info	*p_device = NULL;
	Error_Block				errorBlock;
	int						i;

	deviceid = NOR_DEVICE;

	p_device = platform_device_open(deviceid, 0);
	if(p_device==NULL) {
		platform_write("\nUnable to open NOR Flash\n");
		goto READ_DONE;
	}

	buffer = (uint8_t *) Memory_alloc( NULL, platform_roundup(p_device->page_size, PLATFORM_CACHE_LINE_SIZE), PLATFORM_CACHE_LINE_SIZE, &errorBlock);
	if(!buffer) {
		platform_write("Unable to allocate memory to read NOR flash\n");
		goto READ_DONE;
	}

	memset(buffer, 0, p_device->page_size);
	block = 0;
	page = 0;

	platform_blocknpage_to_offset(p_device->handle, &offset, block, page);

	platform_device_read(p_device->handle, offset, buffer, p_device->page_size);

	for(i=0;i<128;i++)
	{
		platform_write("%02X", buffer[i]);
	}

READ_DONE:
	if(buffer)
		Memory_free(NULL, buffer, platform_roundup(p_device->page_size, PLATFORM_CACHE_LINE_SIZE));

	if(p_device!=NULL)
		platform_device_close(p_device->handle);

	return;
}

//
// Main Thread
//
int StackTest()
{
	int             rc;
	int        		i;
	HANDLE          hCfg;
	QMSS_CFG_T      qmss_cfg;
	CPPI_CFG_T      cppi_cfg;

	/* Get information about the platform so we can use it in various places */
	memset( (void *) &gPlatformInfo, 0, sizeof(platform_info));
	(void) platform_get_info(&gPlatformInfo);

	/* Clear the state of the User LEDs to OFF */
	for (i=0; i < gPlatformInfo.led[PLATFORM_USER_LED_CLASS].count; i++) {
		(void) platform_led(i, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
	}

	/* Initialize the components required to run this application:
     *  (1) QMSS
     *  (2) CPPI
     *  (3) Packet Accelerator
     */
    /* Initialize QMSS */
    if (platform_get_coreid() == 0)
    {
        qmss_cfg.master_core        = 1;
    }
    else
    {
        qmss_cfg.master_core        = 0;
    }
    qmss_cfg.max_num_desc       = MAX_NUM_DESC;
    qmss_cfg.desc_size          = MAX_DESC_SIZE;
    qmss_cfg.mem_region         = Qmss_MemRegion_MEMORY_REGION0;
    if (res_mgr_init_qmss (&qmss_cfg) != 0)
    {
        platform_write ("Failed to initialize the QMSS subsystem \n");
        goto main_exit;
    }
    else
    {
     platform_write ("QMSS successfully initialized \n");
    }

    /* Initialize CPPI */
    if (platform_get_coreid() == 0)
    {
        cppi_cfg.master_core        = 1;
    }
    else
    {
        cppi_cfg.master_core        = 0;
    }
    cppi_cfg.dma_num            = Cppi_CpDma_PASS_CPDMA;
    cppi_cfg.num_tx_queues      = NUM_PA_TX_QUEUES;
    cppi_cfg.num_rx_channels    = NUM_PA_RX_CHANNELS;
    if (res_mgr_init_cppi (&cppi_cfg) != 0)
    {
        platform_write ("Failed to initialize CPPI subsystem \n");
        goto main_exit;
    }
    else
    {
     platform_write ("CPPI successfully initialized \n");
    }


    if (res_mgr_init_pass()!= 0) {
        platform_write ("Failed to initialize the Packet Accelerator \n");
        goto main_exit;
    }
    else
    {
     platform_write ("PA successfully initialized \n");
    }
    //
    // THIS MUST BE THE ABSOLUTE FIRST THING DONE IN AN APPLICATION before
    //  using the stack!!
    //
    rc = NC_SystemOpen( NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT );
    if( rc )
    {
        platform_write("NC_SystemOpen Failed (%d)\n",rc);
        for(;;);
    }

    // Print out our banner
    platform_write(VerStr);

    // Create a new configuration
    hCfg = CfgNew();
    if( !hCfg )
    {
    	platform_write("Unable to create configuration\n");
        goto main_exit;
    }

    // We better validate the length of the supplied names
    if( strlen( DomainName ) >= CFG_DOMAIN_MAX ||
        strlen( HostName ) >= CFG_HOSTNAME_MAX )
    {
    	platform_write("Names too long\n");
        goto main_exit;
    }

    // Add our global hostname to hCfg (to be claimed in all connected domains)
    CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_HOSTNAME, 0,
                 strlen(HostName), (UINT8 *)HostName, 0 );

    // If the IP address is specified, manually configure IP and Gateway
#if defined(_SCBP6618X_) || defined(_EVMTCI6614_) || defined(DEVICE_K2H) || defined(DEVICE_K2K)
    /* SCBP6618x, EVMTCI6614, EVMK2H, EVMK2K always uses DHCP */
    if (0)
#else
    if (!platform_get_switch_state(1))
#endif
    {
        CI_IPNET NA;
        CI_ROUTE RT;
        IPN      IPTmp;

        // Setup manual IP address
        bzero( &NA, sizeof(NA) );
        NA.IPAddr  = inet_addr(LocalIPAddr);
        NA.IPMask  = inet_addr(LocalIPMask);
        strcpy( NA.Domain, DomainName );
        NA.NetType = 0;

        // Add the address to interface 1
        CfgAddEntry( hCfg, CFGTAG_IPNET, 1, 0,
                           sizeof(CI_IPNET), (UINT8 *)&NA, 0 );

        // Add the default gateway. Since it is the default, the
        // destination address and mask are both zero (we go ahead
        // and show the assignment for clarity).
        bzero( &RT, sizeof(RT) );
        RT.IPDestAddr = 0;
        RT.IPDestMask = 0;
        RT.IPGateAddr = inet_addr(GatewayIP);

        // Add the route
        CfgAddEntry( hCfg, CFGTAG_ROUTE, 0, 0,
                           sizeof(CI_ROUTE), (UINT8 *)&RT, 0 );

        // Manually add the DNS server when specified
        IPTmp = inet_addr(DNSServer);
        if( IPTmp )
            CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER,
                         0, sizeof(IPTmp), (UINT8 *)&IPTmp, 0 );
    }
    // Else we specify DHCP
    else
    {
        CI_SERVICE_DHCPC dhcpc;

        // Specify DHCP Service on IF-1
        bzero( &dhcpc, sizeof(dhcpc) );
        dhcpc.cisargs.Mode   = CIS_FLG_IFIDXVALID;
        dhcpc.cisargs.IfIdx  = 1;
        dhcpc.cisargs.pCbSrv = &ServiceReport;
        CfgAddEntry( hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 0,
                     sizeof(dhcpc), (UINT8 *)&dhcpc, 0 );
    }

    //
    // Configure IPStack/OS Options
    //

    // We don't want to see debug messages less than WARNINGS
    rc = DBG_WARN;
    CfgAddEntry( hCfg, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    //
    // This code sets up the TCP and UDP buffer sizes
    // (Note 8192 is actually the default. This code is here to
    // illustrate how the buffer and limit sizes are configured.)
    //

    // UDP Receive limit
    rc = 8192;
    CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT,
                 CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

    //
    // Boot the system using this configuration
    //
    // We keep booting until the function returns 0. This allows
    // us to have a "reboot" command.
    //
    do
    {
        rc = NC_NetStart( hCfg, NetworkOpen, NetworkClose, NetworkIPAddr );
    } while( rc > 0 );

    // Delete Configuration
    CfgFree( hCfg );

    // Close the OS
main_exit:
    NC_SystemClose();
    return(0);
}

//
// System Task Code [ Server Daemon Servers ]
//
static HANDLE hHello=0;
//
// NetworkOpen
//
// This function is called after the configuration has booted
//
static void NetworkOpen()
{
    // Create our local server
    hHello = DaemonNew( SOCK_DGRAM, 0, 7, dtask_udp_hello,
                       OS_TASKPRINORM, OS_TASKSTKNORM, 0, 1 );
}

//
// NetworkClose
//
// This function is called when the network is shutting down,
// or when it no longer has any IP addresses assigned to it.
//
static void NetworkClose()
{
    DaemonFree( hHello );
}

//
// NetworkIPAddr
//
// This function is called whenever an IP address binding is
// added or removed from the system.
//
static void NetworkIPAddr( IPN IPAddr, uint IfIdx, uint fAdd )
{
    IPN IPTmp;

    if( fAdd )
        platform_write("Network Added: ");
    else
        platform_write("Network Removed: ");

    // Print a message
    IPTmp = ntohl( IPAddr );
    platform_write("If-%d:%d.%d.%d.%d\n", IfIdx,
            (UINT8)(IPTmp>>24)&0xFF, (UINT8)(IPTmp>>16)&0xFF,
            (UINT8)(IPTmp>>8)&0xFF, (UINT8)IPTmp&0xFF );
}

//
// Service Status Reports
//
// Here's a quick example of using service status updates
//
static char *TaskName[]  = { "Telnet","HTTP","NAT","DHCPS","DHCPC","DNS" };
static char *ReportStr[] = { "","Running","Updated","Complete","Fault" };
static char *StatusStr[] = { "Disabled","Waiting","IPTerm","Failed","Enabled" };
static void ServiceReport( uint Item, uint Status, uint Report, HANDLE h )
{
    platform_write( "Service Status: %-9s: %-9s: %-9s: %03d\n",
            TaskName[Item-1], StatusStr[Status],
            ReportStr[Report/256], Report&0xFF );

    //
    // Example of adding to the DHCP configuration space
    //
    // When using the DHCP client, the client has full control over access
    // to the first 256 entries in the CFGTAG_SYSINFO space.
    //
    // Note that the DHCP client will erase all CFGTAG_SYSINFO tags except
    // CFGITEM_DHCP_HOSTNAME. If the application needs to keep manual
    // entries in the DHCP tag range, then the code to maintain them should
    // be placed here.
    //
    // Here, we want to manually add a DNS server to the configuration, but
    // we can only do it once DHCP has finished its programming.
    //
    if( Item == CFGITEM_SERVICE_DHCPCLIENT &&
        Status == CIS_SRV_STATUS_ENABLED &&
        (Report == (NETTOOLS_STAT_RUNNING|DHCPCODE_IPADD) ||
         Report == (NETTOOLS_STAT_RUNNING|DHCPCODE_IPRENEW)) )
    {
        IPN IPTmp;

        // Manually add the DNS server when specified
        IPTmp = inet_addr(DNSServer);
        if( IPTmp )
            CfgAddEntry( 0, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER,
                         0, sizeof(IPTmp), (UINT8 *)&IPTmp, 0 );
    }
}
5557.nara_dsp.cfg

This is very critical for my project and I need your help.

Thanks in advance.

Baeyoung

  • Hi,

    When GPIO interrupts were given to EVM board, LED toggle is not working well. I think most of DSP performance is consumed by GPIO interrupt processing.
    I think DSP is working very slowly.

    What do you meant for DSP is working very slowly ?


    When GPIO interrupts were given to EVM board, LED toggle is not working well. I think most of DSP performance is consumed by GPIO interrupt processing.

    LED is not blinking at all ?

    GPIO blinking rate is very less (firing rate) or any interrupt miss ?
    Just try to comment out some particular area "GPIO" or "UART" or "NDK" and figure it out which is causing this slow behaviour.
    Also try to use in combination, NDK with UART and NDK with GPIO etc.,

    We can look into CPU load graph in CCS.
    processors.wiki.ti.com/.../Multicore_System_Analyzer
  • Dear Titus,
    Thanks for your update.
    Actually I'm an old guy for DSP. I used AT&T, Analog Device and TI DSPs. I used to write my own code for all function including interrupts, boot code and etc. So right now I'm a littile suprised with what is done by SYS/BIOS. A lot of thing is done by SYS/BIOS.
    As I told I have two HWI interrupts, one for UART and the other for GPIO.
    I have two SWI interrupts, one for UART character process and the other for LED2 toggle.
    LED2 toggling is test code for GPIO interrupt. Actually SWI for UART interrupt was not working for this test becuase there was no UART input to DSP.
    I have Clock at a rate of 500 period, toggling LED1.
    I am using two LEDs, LED1(Clock task) and LED2(GPIO Swi).
    Of course, my code has NDK but was not used for this test.
    And I checked the code for interrupt process without UART interrupt and IP data senig.
    Before I connected GPIO interrupt to DSP, Clock is toggling LED1 successfully at a rate 0.5 seconds.
    When I connected GPIO interrupt to DSP, LED1 toggle is not working well. Toggling period is not regular. Sometime LED1 is on and off unexpectedly. So I assume DSP is stuck in GPIO HWI and SWI process.
    It seemed that LED2 for GPIO interrupt is working well. GPIO interrupt occur every 12.5us. When I checked signal driving LED2 using oscilloscope, driving signal is pulse train at a rate of 25us.
    SWI for GPIO is priority 15 and SWI for UART is priority 14.
    Why is DSP working slowly? My assumption is like the following.
    When I checked DSP interrupt processing capability, I used UART interrupt.
    Without GPIO interrupt and IP data sending, I was pressing keyboard using Terminal program connected to EVM6678l.
    On Terminal program echoed my continuous input. Within about 200 continuous character inputs, DSP was not working.
    As I told, I was using Clock task, toggling LED1 at a rate of 500 period. LED1 was not toggling. No more character echo.
    Release build showed better UART interrupt processing capability thank Debug build. It means that Release build got more continuous UART inputs.
    I'm a littile suprised with capability SYS/BIOS can't process UART interrupt well. Maybe my code has a problem. I thnk my code is very simple for interrupt processing.
    Can you check setting for nested interrupt and masking option in *.cfg file?
    This issue is very important and need your help. Without solving this problem, I can't go further.
    Thanks in advance.
  • Deat Titus,
    I optimized my code according to your docuement "Keystone Multicore Workshop Lab Manual, SRPR820".
    I suppressed some symbolic debug message, optimization -o3 and etc.
    The code is a little faster but still LED1 is not toggling at 500 period. And when I didn't provide GPIO interrupt, LED1 is toggling expectedly.
    I am doing more test. But I assume DSP is working slowly. GPIO interrupt is only 12.5us. I tink it's not fast for DSP.
    when you check *.cfg file, is DSP running 1GHz?
    I am waiting for your update.
    Thanks in advance.
    Baeyoung
  • Hi,
    Your processor would support 1.2GHz ?
    Are you debugging your code through emulator ?
    If yes, you can configure the gel file to initialize for 1.2GHz if your processor supports.

    I think, you may get much speed when you flash and work instead of emulator debugging.
  • Dear Titus,

    There was something wrong with me.

    I am using gel file provided by CCS.

    I think DSP is set to 1GHz. Also, there is setting by SYS/BIOS (Runtime and Platform Settings) and CPU clock frequency is 1GHz.

    Please check my HWI and SWI functions.

    HWI for UART is like the following:

    Void HWI_UART_Handler(UArg arg)
    {
        CpIntc_clearSysInt(0,148);
        UART_Byte_Recv=UartReadData();
        Swi_post(uartSwiHandle);
    }

    Here is SWi routine for UART:

    void SWI_UART_Handler()
    {
        static int LED0_state = 0;

        if(LED0_state)
             platform_led(0, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
        else
            platform_led(0, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
        LED0_state ^= 1;

        platform_uart_write(UART_Byte_Recv);

        if(UART_Byte_Recv==0x0D) {
            platform_uart_write(0xA);
            Uart_Interrupt_Received_Flag = 1;
            Semaphore_post(uart_sem);
        }
        else {
            if(cmdStringPtr>=MAX_UART_CHAR)
                return;
            if(UART_Byte_Recv!=0x08)
                cmdString[cmdStringPtr++] = UART_Byte_Recv;
            else {
                if(cmdStringPtr>0) {
                    cmdStringPtr -= 1;
                    cmdString[cmdStringPtr] = NULL;
                }
            }
        }
    }

    In the first part of SWI, there is a code to goggle LED0.

    Where there was continuous UART inputs, DSP crashed after about 20 continuous keyboard inputs.

    But, when I removed codes to toggle LED0, DSP was working successfully. It means DSP gets continuous UART input without crash.

    Why does it happen?

    I am looking into the codes for platform_led(). I can't find the reason. This problem took a couple of day and still kept me upset.

    Also, I am checking my code for GPIO interrupt processing. I assume there is something wrong with my hardware.

    I made a daughter board connected to EVM6678l through 80 pin connector. The daughter board is using SPI and pulled down SPIMISO. So LED blinking with GPIO interrupt went wrong. I am coming back with GPIO interrupt code.

    Thanks in advance.

    Baeyoung

  • Dear Titus,

    I am waiting for your help. Please help me.

    Thanks in advance.

    Baeyoung