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?
/* * ======== 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 ); } }
This is very critical for my project and I need your help.
Thanks in advance.
Baeyoung