Ejemplo n.º 1
1
void frs_user_top(void *parameters)
{
    char buf[256];
    vTaskGetRunTimeStats(buf);
    printf("Task\t Abs Time \t Time\n");
    printf(buf);

    /* kill task */
    frs_task_kill_name(NULL);
}
Ejemplo n.º 2
0
	void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer )
	{
    BaseType_t xRunningPrivileged = prvRaisePrivilege();

		vTaskGetRunTimeStats( pcWriteBuffer );
        portRESET_PRIVILEGE( xRunningPrivileged );
	}
Ejemplo n.º 3
0
	void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer )
	{
	BaseType_t xRunningPrivileged = xPortRaisePrivilege();

		vTaskGetRunTimeStats( pcWriteBuffer );
		vPortResetPrivilege( xRunningPrivileged );
	}
Ejemplo n.º 4
0
static unsigned short uslwIPAppsSSIHandler( int iIndex, char *pcBuffer, int iBufferLength )
{
static unsigned int uiUpdateCount = 0;
static char cUpdateString[ 200 ];
extern char *pcMainGetTaskStatusMessage( void );

	/* Unused parameter. */
	( void ) iBufferLength;

	/* The SSI handler function that generates text depending on the index of
	the SSI tag encountered. */
	
	switch( iIndex )
	{
		case ssiTASK_STATS_INDEX :
			vTaskList( ( signed char * ) pcBuffer );
			break;

		case ssiRUN_TIME_STATS_INDEX :
			vTaskGetRunTimeStats( ( signed char * ) pcBuffer );
			break;
	}

	/* Include a count of the number of times an SSI function has been executed
	in the returned string. */
	uiUpdateCount++;
	sprintf( cUpdateString, "\r\n\r\n%u\r\nStatus - %s", uiUpdateCount, pcMainGetTaskStatusMessage() );
	strcat( pcBuffer, cUpdateString );
	return strlen( pcBuffer );
}
Ejemplo n.º 5
0
portBASE_TYPE prvRunTimeStatsCommand(int8_t *pcWriteBuffer,
								  size_t xWriteBufferLen,
								  const int8_t *pcCommandString)
{
	sprintf(pcWriteBuffer, runStatsHdr );
	pcWriteBuffer += strlen(runStatsHdr);
	vTaskGetRunTimeStats(pcWriteBuffer);

	return pdFALSE;
}
Ejemplo n.º 6
0
static unsigned short generate_runtime_stats( void *arg )
{
	( void ) arg;
	lRefreshCount++;
	sprintf( cCountBuf, "<p><br>Refresh count = %d", ( int ) lRefreshCount );
	vTaskGetRunTimeStats( uip_appdata );
	strcat( uip_appdata, cCountBuf );

	return strlen( uip_appdata );
}
Ejemplo n.º 7
0
static retval_t cmd_dump_runtime_stats(const subsystem_t *self, frame_t *iframe, frame_t *oframe) {
#if ( configGENERATE_RUN_TIME_STATS == 1 )
#define FREERTOS_STAT_BUFSIZE_PER_TASK 40
#define CANOPUS_CMOCKERY_ESTIMATED_TASKS_COUNT 42
    signed char buf[CANOPUS_CMOCKERY_ESTIMATED_TASKS_COUNT * FREERTOS_STAT_BUFSIZE_PER_TASK];

    vTaskGetRunTimeStats(buf);
    log_report(LOG_SS_PLATFORM, (const char *)buf);
    FUTURE_HOOK_4(cmd_dump_runtime_stats, buf, sizeof(buf), iframe, oframe);

    return RV_SUCCESS;
#else
    return RV_NOTIMPLEMENTED;
#endif
}
Ejemplo n.º 8
0
Archivo: main.c Proyecto: stmich/BAC2
static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
{
const int8_t * const pcHeader = ( int8_t * ) "Task            Abs Time      % Time\r\n****************************************\r\n";

	( void ) pcCommandString;
	configASSERT( pcWriteBuffer );

	/* This function assumes the buffer length is adequate. */
	( void ) xWriteBufferLen;

	/* Generate a table of task stats. */
	strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader );
	vTaskGetRunTimeStats( pcWriteBuffer + strlen( ( char * ) pcHeader ) );

	/* There is no more data to return after this single string, so return
	pdFALSE. */
	return pdFALSE;
}
Ejemplo n.º 9
0
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
const char * const pcHeader = "Task            Abs Time      % Time\r\n****************************************\r\n";

	/* Remove compile time warnings about unused parameters, and check the
	write buffer is not NULL.  NOTE - for simplicity, this example assumes the
	write buffer length is adequate, so does not check for buffer overflows. */
	( void ) pcCommandString;
	( void ) xWriteBufferLen;
	configASSERT( pcWriteBuffer );

	/* Generate a table of task stats. */
	strcpy( pcWriteBuffer, pcHeader );
	vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );

	/* There is no more data to return after this single string, so return
	pdFALSE. */
	return pdFALSE;
}
Ejemplo n.º 10
0
static portBASE_TYPE prvRunTimeStatsCommand( signed char *pcWriteBuffer, size_t xWriteBufferLen, const signed char * pcCommandString )
{
const char * const pcHeader = "Task            Abs Time      % Time\r\n****************************************\r\n";

	configASSERT( pcWriteBuffer );

	/* This function assumes the buffer length is adequate and does not look
	for parameters. */
	( void ) xWriteBufferLen;
	( void ) pcCommandString;

	/* Generate a table of task stats. */
	strcpy( pcWriteBuffer, pcHeader );
	vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );

	/* There is no more data to return after this single string, so return 
	pdFALSE. */
	return pdFALSE;
}
void runtimestats_print(void)
{
  char *buf;

  /* Allocate memory */
  vTaskSuspendAll();
  buf = (char *) calloc(uxTaskGetNumberOfTasks() * 40, sizeof(char));
  xTaskResumeAll();

  if (buf != NULL)
  {
    /* Get a runtime stats report and write it on the UART */
    vTaskGetRunTimeStats((signed char*) buf);
    uart_write((INT8U *) buf, strlen((char *) buf), portMAX_DELAY);

    /* Free the memory again */
    vTaskSuspendAll();
    free(buf);
    xTaskResumeAll();
  }
}
Ejemplo n.º 12
0
static unsigned short generate_runtime_stats( void *arg )
{
	( void ) arg;
	lRefreshCount++;
	sprintf( cCountBuf, "<p><br>Refresh count = %d", ( int ) lRefreshCount );
	
	#ifdef INCLUDE_HIGH_FREQUENCY_TIMER_TEST
	{
		sprintf( cJitterBuffer, "<p><br>Max high frequency timer jitter = %d peripheral clock periods.<p><br>", ( int ) usMaxJitter );
		vTaskGetRunTimeStats( uip_appdata );
		strcat( uip_appdata, cJitterBuffer );
	}
	#else
	{
		( void ) cJitterBuffer;
		strcpy( uip_appdata, "<p>Run time stats are only available in the debug_with_optimisation build configuration.<p>" );
	}
	#endif	

	strcat( uip_appdata, cCountBuf );

	return strlen( uip_appdata );
}
Ejemplo n.º 13
0
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
const char * const pcHeader = "  Abs Time      % Time\r\n****************************************\r\n";
BaseType_t xSpacePadding;

	/* Remove compile time warnings about unused parameters, and check the
	write buffer is not NULL.  NOTE - for simplicity, this example assumes the
	write buffer length is adequate, so does not check for buffer overflows. */
	( void ) pcCommandString;
	( void ) xWriteBufferLen;
	configASSERT( pcWriteBuffer );

	/* Generate a table of task stats. */
	strcpy( pcWriteBuffer, "Task" );
	pcWriteBuffer += strlen( pcWriteBuffer );

	/* Pad the string "task" with however many bytes necessary to make it the
	length of a task name.  Minus three for the null terminator and half the 
	number of characters in	"Task" so the column lines up with the centre of 
	the heading. */
	for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ )
	{
		/* Add a space to align columns after the task's name. */
		*pcWriteBuffer = ' ';
		pcWriteBuffer++;

		/* Ensure always terminated. */
		*pcWriteBuffer = 0x00;
	}

	strcpy( pcWriteBuffer, pcHeader );
	vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );

	/* There is no more data to return after this single string, so return
	pdFALSE. */
	return pdFALSE;
}
Ejemplo n.º 14
0
extern "C" void vApplicationTickHook()
{
	static unsigned portLONG ulTicksSinceLastDisplay = 0;

	// Called from every tick interrupt. Have enough ticks passed to make it
	// time to perform our health status check again?
	ulTicksSinceLastDisplay++;
	if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
	{
		ulTicksSinceLastDisplay = 0;

		WDT_Feed();

#if configGENERATE_RUN_TIME_STATS == 1
		unsigned long long uptime_usec = ullTaskGetSchedulerUptime();

#if 1
		struct timeval tp;
		int t = gettimeofday(&tp, NULL);
		printf("timeofday = %ld seconds %ld microseconds (code %d)\n", (long)tp.tv_sec, (long)tp.tv_usec, t);
#endif

		printf("Uptime: %u.%06u seconds\n", (unsigned int)(uptime_usec / 1000000), (unsigned int)(uptime_usec % 1000000));

		int8_t *taskListBuffer = (int8_t *)malloc(40 * uxTaskGetNumberOfTasks());
		if (taskListBuffer != NULL)
		{
			vTaskGetRunTimeStats((int8_t *)taskListBuffer);
			puts((const char *)taskListBuffer);
			free(taskListBuffer);
		}
#endif

		// Has an error been found in any task?
		int allGood = 1;
#if 0
		if( xAreBlockingQueuesStillRunning() != pdTRUE )
		{
			printf("ERROR - BLOCKQ\n");
			allGood = 0;
		}

		if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
		{
			printf("ERROR - BLOCKTIM\n");
			allGood = 0;
		}

		if( xAreGenericQueueTasksStillRunning() != pdTRUE )
		{
			printf("ERROR - GENQ\n");
			allGood = 0;
		}

		if( xAreQueuePeekTasksStillRunning() != pdTRUE )
		{
			printf("ERROR - PEEKQ\n");
			allGood = 0;
		}

		if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
		{
			printf("ERROR - DYNAMIC\n");
			allGood = 0;
		}
#endif
		if (allGood == 1)
		{
			printf("All Good.\n");
		}
		fflush(stdout);
	}
}
Ejemplo n.º 15
0
static void prvLCDTask( void *pvParameters )
{
    xQueueMessage xReceivedMessage;
    long lLine = Line1;
    const long lFontHeight = (((sFONT *)LCD_GetFont())->Height);

    /* Buffer into which strings are formatted and placed ready for display on the
    LCD.  Note this is a static variable to prevent it being allocated on the task
    stack, which is too small to hold such a variable.  The stack size is configured
    when the task is created. */
    static char cBuffer[ 512 ];

    /* This function is the only function that uses printf().  If printf() is
    used from any other function then some sort of mutual exclusion on stdout
    will be necessary.

    This is also the only function that is permitted to access the LCD.

    First print out the number of bytes that remain in the FreeRTOS heap.  This
    can be viewed in the terminal IO window within the IAR Embedded Workbench. */
    printf( "%d bytes of heap space remain unallocated\n", xPortGetFreeHeapSize() );

    for( ;; ) {
        /* Wait for a message to be received.  Using portMAX_DELAY as the block
        time will result in an indefinite wait provided INCLUDE_vTaskSuspend is
        set to 1 in FreeRTOSConfig.h, therefore there is no need to check the
        function return value and the function will only return when a value
        has been received. */
        xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY );

        /* Clear the LCD if no room remains for any more text output. */
        if( lLine > Line9 ) {
            LCD_Clear( Blue );
            lLine = 0;
        }

        /* What is this message?  What does it contain? */
        switch( xReceivedMessage.cMessageID ) {
            case mainMESSAGE_BUTTON_UP		:	/* The button poll task has just
												informed this task that the up
												button on the joystick input has
												been pressed or released. */
                sprintf( cBuffer, "Button up = %d", xReceivedMessage.lMessageValue );
                break;

            case mainMESSAGE_BUTTON_SEL		:	/* The select button interrupt
												just informed this task that the
												select button was pressed.
												Generate a table of task run time
												statistics and output this to
												the terminal IO window in the IAR
												embedded workbench. */
                printf( "\nTask\t     Abs Time\t     %%Time\n*****************************************" );
                vTaskGetRunTimeStats( cBuffer );
                printf( cBuffer );

                /* Also print out a message to
                the LCD - in this case the
                pointer to the string to print
                is sent directly in the
                lMessageValue member of the
                message.  This just demonstrates
                a different communication
                technique. */
                sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.lMessageValue );
                break;

            case mainMESSAGE_STATUS			:	/* The tick interrupt hook
												function has just informed this
												task of the system status.
												Generate a string in accordance
												with the status value. */
                prvGenerateStatusMessage( cBuffer, xReceivedMessage.lMessageValue );
                break;

            default							:
                sprintf( cBuffer, "Unknown message" );
                break;
        }

        /* Output the message that was placed into the cBuffer array within the
        switch statement above. */
        LCD_DisplayStringLine( lLine, ( uint8_t * ) cBuffer );

        /* Move onto the next LCD line, ready for the next iteration of this
        loop. */
        lLine += lFontHeight;
    }
}
Ejemplo n.º 16
0
static void prvLCDTask( void *pvParameters )
{
    xQueueMessage xReceivedMessage;

    /* Buffer into which strings are formatted and placed ready for display on the
    LCD.  Note this is a static variable to prevent it being allocated on the task
    stack, which is too small to hold such a variable.  The stack size is configured
    when the task is created. */
    static char cBuffer[ 512 ];
    unsigned char ucLine = 1;


    /* This function is the only function that uses printf().  If printf() is
    used from any other function then some sort of mutual exclusion on stdout
    will be necessary.

    This is also the only function that is permitted to access the LCD.

    First print out the number of bytes that remain in the FreeRTOS heap.  This
    can be viewed in the terminal IO window within the IAR Embedded Workbench. */
    printf( "%d bytes of heap space remain unallocated\n", ( int ) xPortGetFreeHeapSize() );

    /* Just as a test of the port, and for no functional reason, check the task
    parameter contains its expected value. */
    if( pvParameters != mainTASK_PARAMETER_CHECK_VALUE )
    {
        halLcdPrintLine( "Invalid parameter", ucLine,  OVERWRITE_TEXT );
        ucLine++;
    }

    for( ;; )
    {
        /* Wait for a message to be received.  Using portMAX_DELAY as the block
        time will result in an indefinite wait provided INCLUDE_vTaskSuspend is
        set to 1 in FreeRTOSConfig.h, therefore there is no need to check the
        function return value and the function will only return when a value
        has been received. */
        xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY );

        /* Clear the LCD if no room remains for any more text output. */
        if( ucLine > mainMAX_LCD_LINES )
        {
            halLcdClearScreen();
            ucLine = 0;
        }

        /* What is this message?  What does it contain? */
        switch( xReceivedMessage.cMessageID )
        {
        case mainMESSAGE_BUTTON_UP		:	/* The button poll task has just
												informed this task that the up
												button on the joystick input has
												been pressed or released. */
            sprintf( cBuffer, "Button up = %d", ( int ) xReceivedMessage.ulMessageValue );
            break;

        case mainMESSAGE_BUTTON_SEL		:	/* The select button interrupt
												just informed this task that the
												select button was pressed.
												Generate a table of task run time
												statistics and output this to
												the terminal IO window in the IAR
												embedded workbench. */
            printf( "\nTask\t     Abs Time\t     %%Time\n*****************************************" );
            vTaskGetRunTimeStats( ( signed char * ) cBuffer );
            printf( cBuffer );

            /* Also print out a message to
            the LCD - in this case the
            pointer to the string to print
            is sent directly in the
            ulMessageValue member of the
            message.  This just demonstrates
            a different communication
            technique. */
            sprintf( cBuffer, "%s", ( char * ) xReceivedMessage.ulMessageValue );
            break;

        case mainMESSAGE_STATUS			:	/* The tick interrupt hook
												function has just informed this
												task of the system status.
												Generate a string in accordance
												with the status value. */
            prvGenerateStatusMessage( cBuffer, xReceivedMessage.ulMessageValue );
            break;

        default							:
            sprintf( cBuffer, "Unknown message" );
            break;
        }

        /* Output the message that was placed into the cBuffer array within the
        switch statement above, then move onto the next line ready for the next
        message to arrive on the queue. */
        halLcdPrintLine( cBuffer, ucLine,  OVERWRITE_TEXT );
        ucLine++;
    }
}
Ejemplo n.º 17
0
/**
 * \brief Send a JSON string representing the board status.
 *
 * \param name Not used.
 * \param recv_buf Receive buffer.
 * \param recv_len Receive buffer length.
 *
 * \return 0.
 */
static int cgi_status(struct netconn *client, const char *name, char *recv_buf, size_t recv_len)
{
	(void)recv_buf;
	(void)recv_len;
	(void)name;
	uint32_t length = 0;
	uint32_t nb = 11;
	uint32_t i, count, new_entry;

#if LWIP_STATS
	extern uint32_t lwip_tx_rate;
	extern uint32_t lwip_rx_rate;
#else
	volatile uint32_t lwip_tx_rate = 0;
	volatile uint32_t lwip_rx_rate = 0;
#endif

	/* Protect tx_buf buffer from concurrent access. */
	sys_arch_sem_wait(&cgi_sem, 0);

	status.tot_req++;
	status.up_time = xTaskGetTickCount() / 1000;

	/* Update board status. */
	sprintf(status.last_connected_ip, "%d.%d.%d.%d", IP_ADDR_TO_INT_TUPLE(client->pcb.ip->remote_ip.addr));
	sprintf(status.local_ip, "%d.%d.%d.%d", IP_ADDR_TO_INT_TUPLE(client->pcb.ip->local_ip.addr));
	length += sprintf((char *)tx_buf, "{\"board_ip\":\"%s\",\"remote_ip\":\"%s\",\"download\":%u,\"upload\":%u",
								status.local_ip, status.last_connected_ip,
								lwip_rx_rate, lwip_tx_rate);

	/* Turn FreeRTOS stats into JSON. */
	vTaskGetRunTimeStats(freertos_stats);
	length += sprintf((char *)tx_buf + length, ",\"rtos\":{\"10");
	// i = 2 to skip first 13 10 sequence.
	for (i = 2, count = 0, new_entry = 0; i < FREERTOS_STATS_BUFLEN && freertos_stats[i]; ++i) {
		if (freertos_stats[i] == 13) {
			tx_buf[length++] = '\"';
			new_entry = 1;
			continue;
		}
		if (freertos_stats[i] == 10)
			continue;
		if (freertos_stats[i] == 9) {
			count += 1;
			if (count == 4) {
				tx_buf[length++] = '\"';
				tx_buf[length++] = ':';
				tx_buf[length++] = '\"';
				count = 0;
				continue;
			}
		}
		if (count != 0)
			continue;

		if (new_entry == 1) {
			new_entry = 0;
			tx_buf[length++] = ',';
			tx_buf[length++] = '\"';
			/* Append ID to task name since JSON id must be unique. */
			tx_buf[length++] = '0' + nb / 10;
			tx_buf[length++] = '0' + nb % 10;
			nb++;
		}
		tx_buf[length++] = freertos_stats[i];
	}
	tx_buf[length++] = '}';

	char * memp_names[] = {
#define LWIP_MEMPOOL(name,num,size,desc) desc,
#include "lwip/memp_std.h"
	};
	length += sprintf((char *)tx_buf + length, ",\"lwip\":{");
#if MEM_STATS || MEMP_STATS
	length += sprintf((char *)tx_buf + length, "\"HEAP\":{\"Cur\":%d,\"Size\":%d,\"Max\":%d,\"Err\":%u}", lwip_stats.mem.used, lwip_stats.mem.avail, lwip_stats.mem.max, lwip_stats.mem.err);
	if (MEMP_MAX > 0)
		tx_buf[length++] = ',';
#endif
	for (uint32_t z= 0; z < MEMP_MAX; ++z) {
		length += sprintf((char *)tx_buf + length, "\"%s\":{\"Cur\":%d,\"Size\":%d,\"Max\":%d,\"Err\":%u}", memp_names[z], lwip_stats.memp[z].used, lwip_stats.memp[z].avail, lwip_stats.memp[z].max, lwip_stats.memp[z].err);
		if (z + 1 < MEMP_MAX)
			tx_buf[length++] = ',';
	}
	tx_buf[length++] = '}';

	/* Remaining board status. */
	length += sprintf((char *)tx_buf + length, ",\"up_time\":%u,\"tot_req\":%u}", status.up_time, status.tot_req);

	/* Send answer. */
	http_sendOk(client, HTTP_CONTENT_JSON);
	/* Use NETCONN_COPY to avoid corrupting the buffer after releasing the semaphore. */
	netconn_write(client, tx_buf, strlen((char *)tx_buf), NETCONN_COPY);

	/* Release semaphore to allow further use of tx_buf. */
	sys_sem_signal(&cgi_sem);

	return 0;
}
Ejemplo n.º 18
0
//==================================================================================
void vKeyHandlerTask( void *pvParameters )
{ // Key handling is a continuous process and as such the task 
	// is implemented using an infinite loop (as most real time 
	// tasks are). 
	static uint16_t RegKn = 0, RegKnOld = 0;
	char stat_buff[150];
	u8 i=0, j=0;
	
	for( ;; )
	{
		
#if(( configGENERATE_RUN_TIME_STATS == 1 ) && (DEBUG_ON == 1 ))
		if( one_sec )
		{
			i=0; 
			j=0;
			
			one_sec = false;
			
			for( i=0; i<150; i++ )
				stat_buff[i] = 0;
			
			//vTaskList(stat_buff);
			vTaskGetRunTimeStats( stat_buff );
			
			i = 99;
			while( !stat_buff[i] )
				i--;
			
			printf("%c[1;1f%c[J", 27, 27); //ClearScreen
			
			while( j<i )
			{
				putchar(stat_buff[j]);
				++j;
			}
		}
#endif		
		
		if(!(MDR_PORTC -> RXTX & 0x10))
			RegKn |= 1;
		else
			RegKn &= 0xfffe;
		
		if(!(MDR_PORTC -> RXTX & 0x20))
			RegKn |= 2;
		else
			RegKn &=0xfffd;
		
		if(!(MDR_PORTC -> RXTX & 0x40))
			RegKn |= 4;
		else
			RegKn &= 0xfffb;
		
		if(!(MDR_PORTC -> RXTX & 0x80))
			RegKn |= 8;
		else
			RegKn &= 0xfff7;

		if(!(MDR_PORTC -> RXTX & 0x100))
			RegKn |= 0x10;
		else
			RegKn &= 0xffef;
		
		if(!(MDR_PORTC->RXTX & 0x200))
			RegKn |= 0x20;
		else
			RegKn &= 0xffdf;
		
		if(!(MDR_PORTC -> RXTX & 0x400))
			RegKn |= 0x40;
		else
			RegKn &= 0xffbf;
		
		if(!(MDR_PORTC -> RXTX & 0x800))
			RegKn |= 0x80;
		else
			RegKn &= 0xff7f;

		if(!(MDR_PORTC -> RXTX & 0x8))
			RegKn |= 0x100;
		else
			RegKn &= 0xfeff;

		if(!(MDR_PORTC -> RXTX & 0x1000))
			RegKn |= 0x200;
		else
			RegKn &= 0xfdff;
		
		if(!(MDR_PORTC -> RXTX & 0x2000))
			RegKn |= 0x400;
		else
			RegKn &= 0xfbff;
		
		if(!(MDR_PORTC -> RXTX & 0x4000))
			RegKn |= 0x800;
		else
			RegKn &= 0xf7ff;
		
		if(!(MDR_PORTC -> RXTX & 0x8000))
			RegKn |= 0x1000;
		else
			RegKn &= 0xefff;


		if(RegKnOld == RegKn)
		{
			//RegS = RegKn;
			//PKDU_Status.Ctrl_BTN = RegS;
		}
		else
			RegKnOld = RegKn;
		
		vTaskDelay( 50 );
	}
}