/*
* File : benchmark.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, 2007, 2008 RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
*
* Change Logs:
* Date Author Notes
* 2008-08-31 Bernard the first version
*/
#include
#include
#include
/*
* benchmark for AT91RM9200 benchmark
*
* mck = 59904000 Hz
* TC2, mck/32
*/
#define TC2_CV *((volatile unsigned long*)0xFFFA0090) /* (TC2) Counter Value */
/* benchmark utility */
void set_tracepoint(rt_int32_t level)
{
static rt_uint16_t value;
rt_uint16_t v;
if (level == 0)
{
value = TC2_CV;
}
else
{
v = TC2_CV;
rt_kprintf("CV: 0x%04x
", v - value);
}
}
rt_thread_t thread1 = RT_NULL;
rt_thread_t thread2 = RT_NULL;
rt_thread_t thread3 = RT_NULL;
void thread1_entry(void* parameter)
{
while (1)
{
rt_thread_resume(thread2);
/* init trace point */
set_tracepoint(0);
/* there is no auto schedule, call scheduler */
rt_schedule();
rt_thread_delay(50);
}
}
void thread2_entry(void* parameter)
{
while (1)
{
rt_thread_suspend(thread2);
/* there is no auto schedule, call scheduler */
rt_schedule();
set_tracepoint(1);
}
}
void thread3_entry(void* parameter)
{
rt_kprintf("thread3 entry
");
while (1)
{
rt_thread_suspend(thread3);
/* there is no auto schedule, call scheduler */
rt_schedule();
/* trigger trace point */
set_tracepoint(1);
}
}
void thread_benchmark()
{
if (thread1 != RT_NULL)
{
/* delete thread 1 */
rt_thread_delete(thread1);
thread1 = RT_NULL;
}
if (thread2 != RT_NULL)
{
/* delete thread 2 */
rt_thread_delete(thread2);
thread2 = RT_NULL;
}
/* create thread 1 and thread 2*/
thread1 = rt_thread_create("tid1", thread1_entry, RT_NULL,
1024, 250, 20);
rt_thread_startup(thread1);
thread2 = rt_thread_create("tid2", thread2_entry, RT_NULL,
1024, 200, 20);
rt_thread_startup(thread2);
}
/* isr handle, in tc 1 interrupt */
void isr_handler(int irqno)
{
static volatile rt_uint32_t cnt = 0;
volatile rt_uint32_t dummy;
dummy = REG_IN32(AT9200_TC1_SR, 0);
if (cnt == 100)
{
rt_kprintf("trigger thread3
");
cnt = 0;
rt_thread_resume(thread3);
/* there is no auto schedule, call scheduler */
rt_schedule();
/* init trace point */
set_tracepoint(0);
}
else cnt ++;
}
void isr_benchmark()
{
rt_uint32_t result;
rt_uint32_t value;
if (thread3 != RT_NULL)
{
/* delete thread 3 */
result = rt_thread_delete(thread3);
RT_ASSERT(result == RT_EOK);
thread3 = RT_NULL;
}
/* init time counter 1 */
value = REG_IN32(AT9200_TC1_SR, 0); /* read and clear status register */
REG_OUT32(AT9200_TC1_CCR, 0, (1 << 1)); /* disable timer */
REG_OUT32(AT9200_PMC_PCER, 0, (1 << TC1_VEC)); /* enable peripheral clock in pmc for tc0 */
REG_OUT32(AT9200_TC1_CMR, 0, 0x4004); /* timer clock5, lsck, 32768 Hz */
REG_OUT32(AT9200_TC1_RC, 0, 0x147); /* 100 tick per second */
REG_OUT32(AT9200_TC1_IER, 0, (1 << 4)); /* enable RC compare interrupt */
REG_OUT32(AT9200_TC1_CCR, 0, 0x05); /* enable clock counter and software trigger */
/* timer counter interrupt init */
REG_OUT32(AT9200_AIC_SMR, TC1_VEC*4, 0x02); /* interrupt trigger mode & priority */
REG_OUT32(AT9200_AIC_ICCR, 0, (1 << TC1_VEC)); /* clear the TC0 interrupt */
REG_OUT32(AT9200_AIC_IECR, 0, (1 << TC1_VEC)); /* enable the TC0 interrupt */
/* install int handler & unmask immediately*/
rt_hw_interrupt_install(TC1_VEC, isr_handler, RT_NULL);
rt_hw_interrupt_umask(TC1_VEC);
/* create thread 3 and startup */
thread3 = rt_thread_create("tid3", thread3_entry, RT_NULL,
1024, 180, 20);
result = rt_thread_startup(thread3);
RT_ASSERT(result == RT_EOK);
}
int rt_application_init()
{
rt_uint32_t value;
thread1 = thread2 = thread3 = RT_NULL;
/* init time counter 1 */
value = REG_IN32(AT9200_TC2_SR, 0); /* read and clear status register */
REG_OUT32(AT9200_TC2_CCR, 0, (1 << 1)); /* disable timer */
REG_OUT32(AT9200_PMC_PCER, 0, (1 << TC2_VEC)); /* enable peripheral clock in pmc for tc0 */
REG_OUT32(AT9200_TC2_CMR, 0, 0x2); /* timer clock3, mck/32 Hz */
REG_OUT32(AT9200_TC2_RC, 0, 0x147); /* 100 tick per second */
REG_OUT32(AT9200_TC2_CCR, 0, 0x05); /* enable clock counter and software trigger */
#ifdef RT_USING_FINSH
finsh_syscall_append("tbenchmark", (syscall_func)thread_benchmark);
finsh_syscall_append("ibenchmark", (syscall_func)isr_benchmark);
#endif
return 0;
}