This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Alarms and Threads Program Problem :: Help Required


Hello,

I am trying to write a program that has 3 threads executing for 1,2,1 seconds each.
These threads must each execute every 5,6,4 seconds respectively.


(Actually in Program I have multiplied these by a factor of 40 ).

I have tried the following program. One might expect the timing to get screwed up, but
actually the application hangs after saying the following :


"Thread 2A :: Time Before Execution is 1"
hal_isr_default(33) : data (0)
"Thread 2A :: Time After Execution is 27"
"Thread 3 finished at :: 27"

Then I get something like
$..thread .. and some weird numbers ...

PS : Note that it is Thread 3 that says it is finishing.

Can someone tell me where am I going wrong ??

- Vamshi

Misc Data :
   - Using Bitmap Scheduler
   - Template is Kernel
   - Turned Cache Off
   - i386 Target with Realtek NIC card.
#include <cyg/kernel/kapi.h>

#include <stdio.h>
#include <stdlib.h>

#define RVK 40


/*

	Thread Data-Structure for 3 threads.

*/

cyg_thread thread_s[3];




/*

	Stack Space for 3 threads

*/

char stack[3][4096];




/*

	Handles for threads.
	Also thread entry functions

*/

cyg_handle_t modeA_thread1, modeA_thread2, modeA_thread3;
cyg_thread_entry_t thread1A_entry, thread2A_entry, thread3A_entry;




/*

	Forward-Definition of functions

*/

void thread1A_alarm_func(cyg_handle_t, cyg_addrword_t);
void thread2A_alarm_func(cyg_handle_t, cyg_addrword_t);
void thread3A_alarm_func(cyg_handle_t, cyg_addrword_t);



/*

	Alarms and Counters related Data Structures

*/

cyg_handle_t thread_counter[3], system_clockH[3], thread_alarmH[3];
cyg_alarm thread_alarm[3];




/*

	Kernel Flags

*/

cyg_flag_t flag[3];




/*

	Starting the application.

*/


void cyg_user_start(void)
{


	/*

		Create 3 threads 1A, 2A, 3A .

	*/

	cyg_thread_create(6,thread1A_entry,(cyg_addrword_t) 0,"Mode A thread 1",
		 (void *) stack[0],4096,&modeA_thread1,&thread_s[0]);

	cyg_thread_create(4,thread2A_entry,(cyg_addrword_t) 0,"Mode A thread 2",
		 (void *) stack[1],4096,&modeA_thread2,&thread_s[1]);

	cyg_thread_create(5,thread3A_entry,(cyg_addrword_t) 0,"Mode A thread 3",
		 (void *) stack[2],4096,&modeA_thread3,&thread_s[2]);

	
	/*

		Intialize the Kernel Flags

	*/

	cyg_flag_init(&flag[0]);
	cyg_flag_init(&flag[1]);
	cyg_flag_init(&flag[2]);


	/*

		Initialize the alarms
		Period of each thread is (200/240/120) ticks of real-time clock.

	*/

	cyg_thread_resume(modeA_thread1);
	cyg_thread_resume(modeA_thread2);
	cyg_thread_resume(modeA_thread3);
}


void thread1A_entry(cyg_addrword_t data)
{	
	int i,j,temp;
	
	system_clockH[0] = cyg_real_time_clock();
	cyg_clock_to_counter(system_clockH[0], &thread_counter[0]);

	cyg_alarm_create(thread_counter[0],thread1A_alarm_func,
		(cyg_addrword_t) 0,	&thread_alarmH[0], &thread_alarm[0]);

	cyg_alarm_initialize(thread_alarmH[0],cyg_current_time()+200,200);

	for(;;)
	{

		/*

			The following code executes for 40 ticks (approx) .
			This was determined experimentally.

		*/

		diag_printf("Thread 1A :: Time Before Processing :: is %u\n",
			(unsigned int) cyg_current_time());

		for(i=0;i<4600;i++)
		{
			for(j=0;j<10000;j++)
			{
				;
			}
		}					



		diag_printf("Thread 1A :: Time After Processing :: %u\n",
			(unsigned int) cyg_current_time());
	
		/*

			Wait for Kernel Flag to Signal.

		*/
	
		cyg_flag_wait(&flag[0],0x1,
			CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);
	}
}


void thread2A_entry(cyg_addrword_t data)
{
	int i,j;

	system_clockH[1] = cyg_real_time_clock();
	cyg_clock_to_counter(system_clockH[1], &thread_counter[1]);

	cyg_alarm_create(thread_counter[1],thread2A_alarm_func,
		(cyg_addrword_t) 0, &thread_alarmH[1], &thread_alarm[1]);

	cyg_alarm_initialize(thread_alarmH[1],cyg_current_time()+240,240);

	for(;;)
	{
		/*
			The following code executes for 80 ticks (approx) .
			This was determined experimentally.
		*/

		diag_printf("Thread 2A :: Time Before Processing is %u \n",
			(unsigned int) cyg_current_time());

		for(i=0;i<9206;i++)
		{
			for(j=0;j<10000;j++)
			{
				;
			}
		}

		diag_printf("Thread A2 :: Time After Processing is %u \n",				(unsigned int) cyg_current_time());

		/*
			Wait for Kernel Flag to Signal.
		*/

		cyg_flag_wait(&flag[1],0x1,
			CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);
	}
}



void thread3A_entry(cyg_addrword_t data)
{
	int i,j;

	system_clockH[2] = cyg_real_time_clock();
	cyg_clock_to_counter(system_clockH[2], &thread_counter[2]);

	cyg_alarm_create(thread_counter[2],thread3A_alarm_func,
		(cyg_addrword_t) 0, &thread_alarmH[2], &thread_alarm[2]);

	cyg_alarm_initialize(thread_alarmH[2],cyg_current_time()+160,160);
	
	for(;;)
	{

		/*
			The following code executes for 40 ticks (approx) .
			This was determined experimentally.
		*/

		diag_printf("Thread 3A :: Time Before Processing is %u \n",
			(unsigned int) cyg_current_time());

		for(i=0;i<4600;i++)
		{
			for(j=0;j<10000;j++)
			{
				;
			}
		}

		diag_printf("Thread 3A :: Time After Processing is %u \n",
			(unsigned int) cyg_current_time());

		/*
	
			Wait for Kernel Flag to Signal.

		*/

		cyg_flag_wait(&flag[2],0x1,
			CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);

	}
}



/*
	Alarm-Handlers that suspend the various threads.
*/

void thread1A_alarm_func(cyg_handle_t alarm, cyg_addrword_t data)
{
	diag_printf("Thread 1 finished at :: %u \n",
		(unsigned int) cyg_current_time());

	cyg_flag_setbits(&flag[0], 0x1);
}



void thread2A_alarm_func(cyg_handle_t alarm, cyg_addrword_t data)
{
	diag_printf("Thread 2 finished at :: %u \n",
		(unsigned int) cyg_current_time());

	cyg_flag_setbits(&flag[1], 0x1);
}


void thread3A_alarm_func(cyg_handle_t alarm, cyg_addrword_t data)
{
	diag_printf("Thread 3 finished at :: %u \n",
		(unsigned int) cyg_current_time());

	cyg_flag_setbits(&flag[2], 0x1);
}

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]