2025-06-27 00:32:57 +08:00
/*
* author : prife ( goprife @ gmail . com )
* date : 2013 / 01 / 14 01 : 18 : 50
* version : v 0.2 .0
*/
# include <rtthread.h>
# include <stdio.h>
# include <stdlib.h>
# include <pthread.h>
# include <signal.h>
# include <unistd.h>
# include <semaphore.h>
# include <time.h>
# include <sys/time.h>
//#define TRACE printf
# define TRACE(...)
typedef struct _thread
{
pthread_t pthread ;
void ( * task ) ( void * ) ;
void * para ;
void ( * exit ) ( void ) ;
sem_t sem ;
rt_thread_t rtthread ;
int status ;
void * data ;
} thread_t ;
# define THREAD_T(thread) ((thread_t *)thread)
# define MSG_SUSPEND SIGUSR1 /* 10 */
# define MSG_RESUME SIGUSR2
# define MSG_TICK SIGALRM /* 14 */
# define TIMER_TYPE ITIMER_REAL
# define MAX_INTERRUPT_NUM ((unsigned int)sizeof(unsigned int) * 8)
# define INTERRUPT_ENABLE 0
# define INTERRUPT_DISABLE 1
2025-07-05 19:47:28 +08:00
/* <20> ̹߳<DFB3> <CCB9> <EFBFBD> ״̬<D7B4> <CCAC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȡֵ */
2025-06-27 00:32:57 +08:00
# define SUSPEND_LOCK 0
# define SUSPEND_SIGWAIT 1
# define THREAD_RUNNING 2
/* interrupt flag, if 1, disable, if 0, enable */
static long interrupt_disable_flag ;
//static int systick_signal_flag;
/* flag in interrupt handling */
rt_uint32_t rt_interrupt_from_thread , rt_interrupt_to_thread ;
rt_uint32_t rt_thread_switch_interrupt_flag ;
/* interrupt event mutex */
static pthread_mutex_t * ptr_int_mutex ;
static pthread_cond_t cond_int_hit ; /* interrupt occured! */
static volatile unsigned int cpu_pending_interrupts ;
static int ( * cpu_isr_table [ MAX_INTERRUPT_NUM ] ) ( void ) = { 0 } ;
static pthread_t mainthread_pid ;
/* function definition */
static void start_sys_timer ( void ) ;
static int tick_interrupt_isr ( void ) ;
static void mthread_signal_tick ( int sig ) ;
static int mainthread_scheduler ( void ) ;
int signal_install ( int sig , void ( * func ) ( int ) )
{
struct sigaction act ;
/* set the signal handler */
act . sa_handler = func ;
sigemptyset ( & act . sa_mask ) ;
act . sa_flags = 0 ;
sigaction ( sig , & act , 0 ) ;
}
int signal_mask ( void )
{
sigset_t sigmask , oldmask ;
/* set signal mask */
sigemptyset ( & sigmask ) ;
sigaddset ( & sigmask , SIGALRM ) ;
pthread_sigmask ( SIG_BLOCK , & sigmask , & oldmask ) ;
}
static void thread_suspend_signal_handler ( int sig )
{
sigset_t sigmask ;
pthread_t pid = pthread_self ( ) ;
thread_t * thread_from ;
thread_t * thread_to ;
rt_thread_t tid ;
if ( sig ! = MSG_SUSPEND )
{
printf ( " get an unexpected signal <%d>, exit \n " , sig ) ;
exit ( EXIT_FAILURE ) ;
}
thread_from = ( thread_t * ) rt_interrupt_from_thread ;
thread_to = ( thread_t * ) rt_interrupt_to_thread ;
2025-07-05 19:47:28 +08:00
/* ע<> ⣡<EFBFBD> <E2A3A1> ʱ rt_thread_self<6C> <66> ֵ<EFBFBD> <D6B5> to<74> ̵߳<DFB3> ֵ<EFBFBD> <D6B5> */
2025-06-27 00:32:57 +08:00
tid = rt_thread_self ( ) ;
/* FIXME RT_ASSERT(thread_from->pthread == pid); */
RT_ASSERT ( ( thread_t * ) ( tid - > sp ) = = thread_to ) ;
TRACE ( " signal: SIGSUSPEND suspend <%s> \n " , thread_from - > rtthread - > name ) ;
2025-07-05 19:47:28 +08:00
/* ʹ <> <CAB9> sigwait<69> <74> <EFBFBD> <EFBFBD> sigsuspend<6E> <64> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> from<6F> ߳<EFBFBD> */
2025-06-27 00:32:57 +08:00
//sem_wait(&thread_from->sem);
sigemptyset ( & sigmask ) ;
sigaddset ( & sigmask , MSG_RESUME ) ;
2025-07-05 19:47:28 +08:00
/* Beginnig Linux Programming<6E> <67> ˵<EFBFBD> <CBB5> <EFBFBD> <EFBFBD> <EFBFBD> źŴ<C5BA> <C5B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> У <EFBFBD> <D0A3> <EFBFBD> <EFBFBD> źžͻᱻ<CDBB> <E1B1BB> <EFBFBD> Σ<EFBFBD>
* <EFBFBD> Է <EFBFBD> ֹ <EFBFBD> ظ <EFBFBD> ִ <EFBFBD> <EFBFBD> <EFBFBD> ź Ŵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2025-06-27 00:32:57 +08:00
*/
thread_from - > status = SUSPEND_SIGWAIT ;
if ( sigwait ( & sigmask , & sig ) ! = 0 )
{
printf ( " sigwait faild, %d \n " , sig ) ;
}
thread_to = ( thread_t * ) rt_interrupt_to_thread ;
RT_ASSERT ( thread_to = = thread_from ) ;
thread_to - > status = THREAD_RUNNING ;
TRACE ( " signal: SIGSUSPEND resume <%s> \n " , thread_from - > rtthread - > name ) ;
}
static void thread_resume_signal_handler ( int sig )
{
sigset_t sigmask ;
pthread_t pid = pthread_self ( ) ;
thread_t * thread_from ;
thread_t * thread_to ;
rt_thread_t tid ;
thread_from = ( thread_t * ) rt_interrupt_from_thread ;
thread_to = ( thread_t * ) rt_interrupt_to_thread ;
2025-07-05 19:47:28 +08:00
/* ע<> ⣡<EFBFBD> <E2A3A1> ʱ rt_thread_self<6C> <66> ֵ<EFBFBD> <D6B5> to<74> ̵߳<DFB3> ֵ<EFBFBD> <D6B5> */
2025-06-27 00:32:57 +08:00
tid = rt_thread_self ( ) ;
RT_ASSERT ( ( thread_t * ) ( tid - > sp ) = = thread_to ) ;
TRACE ( " signal: SIGRESUME resume <%s> \n " , thread_to - > rtthread - > name ) ;
}
static void * thread_run ( void * parameter )
{
rt_thread_t tid ;
thread_t * thread ;
thread = THREAD_T ( parameter ) ;
int res ;
/* set signal mask, mask the timer! */
signal_mask ( ) ;
thread - > status = SUSPEND_LOCK ;
TRACE ( " pid <%08x> stop on sem... \n " , ( unsigned int ) ( thread - > pthread ) ) ;
sem_wait ( & thread - > sem ) ;
tid = rt_thread_self ( ) ;
TRACE ( " pid <%08x> tid <%s> starts... \n " , ( unsigned int ) ( thread - > pthread ) ,
tid - > name ) ;
thread - > rtthread = tid ;
thread - > task ( thread - > para ) ;
TRACE ( " pid <%08x> tid <%s> exit... \n " , ( unsigned int ) ( thread - > pthread ) ,
tid - > name ) ;
thread - > exit ( ) ;
/*TODO:
2025-07-05 19:47:28 +08:00
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> е <EFBFBD> pthread_exit <EFBFBD> <EFBFBD> Զ û <EFBFBD> л <EFBFBD> <EFBFBD> <EFBFBD> ִ <EFBFBD> У <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ <EFBFBD> <EFBFBD> threead - > exit <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* <EFBFBD> ᷢ <EFBFBD> <EFBFBD> <EFBFBD> ߳ <EFBFBD> <EFBFBD> л <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ý <EFBFBD> <EFBFBD> <EFBFBD> pthread <EFBFBD> ߳ ̹ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ը <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ľ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ź Ÿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߳ ̣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߳ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ٴ λ <EFBFBD> <EFBFBD> Ѵ <EFBFBD> <EFBFBD> ߳ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Զ <EFBFBD> <EFBFBD> ˳ <EFBFBD> <EFBFBD> <EFBFBD>
2025-06-27 00:32:57 +08:00
*/
//sem_destroy(&thread->sem);
pthread_exit ( NULL ) ;
}
static int thread_create (
thread_t * thread , void * task , void * parameter , void * pexit )
{
int res ;
pthread_attr_t attr ;
thread - > task = task ;
thread - > para = parameter ;
thread - > exit = pexit ;
if ( sem_init ( & thread - > sem , 0 , 0 ) ! = 0 )
{
printf ( " init thread->sem failed, exit \n " ) ;
exit ( EXIT_FAILURE ) ;
}
/* No need to join the threads. */
pthread_attr_init ( & attr ) ;
pthread_attr_setdetachstate ( & attr , PTHREAD_CREATE_DETACHED ) ;
/* create a posix thread */
res = pthread_create ( & thread - > pthread , & attr , & thread_run , ( void * ) thread ) ;
if ( res )
{
printf ( " pthread create faild, <%d> \n " , res ) ;
exit ( EXIT_FAILURE ) ;
}
return 0 ;
}
/* resume the thread */
static int thread_resume ( thread_t * thread )
{
sem_post ( & thread - > sem ) ;
}
rt_uint8_t * rt_hw_stack_init (
void * pEntry ,
void * pParam ,
rt_uint8_t * pStackAddr ,
void * pExit )
{
thread_t * thread ;
thread = ( thread_t * ) ( pStackAddr - sizeof ( thread_t ) ) ;
/* set the filed to zero */
memset ( thread , 0x00 , sizeof ( thread_t ) ) ;
thread_create ( thread , pEntry , pParam , pExit ) ;
//TRACE("thread %x created\n", (unsigned int)thread_table[t].pthread);
return ( rt_uint8_t * ) thread ;
}
rt_base_t rt_hw_interrupt_disable ( void )
{
long back ;
if ( ptr_int_mutex = = NULL )
{
return 0 ;
}
pthread_mutex_lock ( ptr_int_mutex ) ;
back = interrupt_disable_flag ;
interrupt_disable_flag = INTERRUPT_DISABLE ;
/*TODO: It may need to unmask the signal */
return back ;
}
void rt_hw_interrupt_enable ( rt_base_t level )
{
struct rt_thread * tid ;
pthread_t pid ;
thread_t * thread_from ;
thread_t * thread_to ;
if ( ptr_int_mutex = = NULL )
return ;
interrupt_disable_flag = level ;
pthread_mutex_unlock ( ptr_int_mutex ) ;
2025-07-05 19:47:28 +08:00
/* <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ѿ<EFBFBD> <D1BE> ж<EFBFBD> <D0B6> <EFBFBD> Ȼ<EFBFBD> ر<EFBFBD> */
2025-06-27 00:32:57 +08:00
if ( interrupt_disable_flag )
{
return ;
}
2025-07-05 19:47:28 +08:00
/* <20> <> ʾ <EFBFBD> <CABE> ǰ<EFBFBD> жϴ<D0B6> <CFB4> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> й<EFBFBD> <D0B9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> */
2025-06-27 00:32:57 +08:00
pthread_mutex_lock ( ptr_int_mutex ) ;
if ( ! cpu_pending_interrupts )
{
pthread_mutex_unlock ( ptr_int_mutex ) ;
return ;
}
thread_from = ( thread_t * ) rt_interrupt_from_thread ;
thread_to = ( thread_t * ) rt_interrupt_to_thread ;
tid = rt_thread_self ( ) ;
pid = pthread_self ( ) ;
//pid != mainthread_pid &&
if ( thread_from - > pthread = = pid )
{
2025-07-05 19:47:28 +08:00
/* ע<> <D7A2> <EFBFBD> <EFBFBD> <EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> RTT<54> <54> ͨ<EFBFBD> ̺߳<DFB3> <CCBA> <EFBFBD> <EFBFBD> ܺ<EFBFBD> <DCBA> <EFBFBD> <EFBFBD> <EFBFBD> ִ<EFBFBD> е ģ<D0B5>
* from <EFBFBD> ߳ ̾ <EFBFBD> <EFBFBD> ǵ <EFBFBD> ǰ rtt <EFBFBD> ߳ <EFBFBD> */
/* <20> <> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> й<EFBFBD> <D0B9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж<EFBFBD> <D0B6> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> */
2025-06-27 00:32:57 +08:00
TRACE ( " conswitch: P in pid<%x> ,suspend <%s>, resume <%s>! \n " ,
( unsigned int ) pid ,
thread_from - > rtthread - > name ,
thread_to - > rtthread - > name ) ;
cpu_pending_interrupts - - ;
thread_from - > status = SUSPEND_LOCK ;
pthread_mutex_unlock ( ptr_int_mutex ) ;
2025-07-05 19:47:28 +08:00
/* <20> <> <EFBFBD> ѱ<EFBFBD> <D1B1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߳<EFBFBD> */
2025-06-27 00:32:57 +08:00
if ( thread_to - > status = = SUSPEND_SIGWAIT )
{
pthread_kill ( thread_to - > pthread , MSG_RESUME ) ;
}
else if ( thread_to - > status = = SUSPEND_LOCK )
{
sem_post ( & thread_to - > sem ) ;
}
else
{
printf ( " conswitch: should not be here! %d \n " , __LINE__ ) ;
exit ( EXIT_FAILURE ) ;
}
2025-07-05 19:47:28 +08:00
/* <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> <EFBFBD> ߳<EFBFBD> */
2025-06-27 00:32:57 +08:00
sem_wait ( & thread_from - > sem ) ;
pthread_mutex_lock ( ptr_int_mutex ) ;
thread_from - > status = THREAD_RUNNING ;
pthread_mutex_unlock ( ptr_int_mutex ) ;
}
else
{
2025-07-05 19:47:28 +08:00
/* ע<> <D7A2> <EFBFBD> <EFBFBD> <EFBFBD> δ<EFBFBD> <CEB4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڶ<EFBFBD> <DAB6> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> У <EFBFBD>
* 1. <EFBFBD> <EFBFBD> system tick <EFBFBD> <EFBFBD> ִ <EFBFBD> У <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߳ ̵ <EFBFBD> SIGALRM <EFBFBD> ź Ŵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ִ <EFBFBD> <EFBFBD>
* 2. <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߳ <EFBFBD> <EFBFBD> е <EFBFBD> <EFBFBD> ã <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڻ <EFBFBD> ȡ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߳ <EFBFBD> <EFBFBD> е <EFBFBD> <EFBFBD> <EFBFBD>
2025-06-27 00:32:57 +08:00
*/
TRACE ( " conswitch: S in pid<%x> ,suspend <%s>, resume <%s>! \n " ,
( unsigned int ) pid ,
thread_from - > rtthread - > name ,
thread_to - > rtthread - > name ) ;
cpu_pending_interrupts - - ;
2025-07-05 19:47:28 +08:00
/* <20> <> Ҫ<EFBFBD> ѽ<EFBFBD> <D1BD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> ,<2C> Է<EFBFBD> ֹ<EFBFBD> <D6B9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> */
2025-06-27 00:32:57 +08:00
pthread_mutex_unlock ( ptr_int_mutex ) ;
2025-07-05 19:47:28 +08:00
/* <20> <> <EFBFBD> <EFBFBD> from<6F> ߳<EFBFBD> */
2025-06-27 00:32:57 +08:00
pthread_kill ( thread_from - > pthread , MSG_SUSPEND ) ;
2025-07-05 19:47:28 +08:00
/* ע<> ⣺<EFBFBD> <E2A3BA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫȷ<D2AA> <C8B7> <EFBFBD> ̱߳<DFB3> <CCB1> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> 312<31> о ͺ ܿ<CDBA> <DCBF> ܾͻᱨ<CDBB> <E1B1A8> <EFBFBD> ˳<EFBFBD>
* <EFBFBD> <EFBFBD> Ϊ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߳ <EFBFBD> <EFBFBD> <EFBFBD> ͨ <EFBFBD> <EFBFBD> <EFBFBD> ź <EFBFBD> ʵ <EFBFBD> ֵ ģ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> Ҫ ȷ <EFBFBD> <EFBFBD> <EFBFBD> ߳ ̹ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> */
2025-06-27 00:32:57 +08:00
while ( thread_from - > status ! = SUSPEND_SIGWAIT )
{
sched_yield ( ) ;
}
2025-07-05 19:47:28 +08:00
/* <20> <> <EFBFBD> <EFBFBD> to<74> ߳<EFBFBD> */
2025-06-27 00:32:57 +08:00
if ( thread_to - > status = = SUSPEND_SIGWAIT )
{
pthread_kill ( thread_to - > pthread , MSG_RESUME ) ;
}
else if ( thread_to - > status = = SUSPEND_LOCK )
{
sem_post ( & thread_to - > sem ) ;
}
else
{
printf ( " conswitch: should not be here! %d \n " , __LINE__ ) ;
exit ( EXIT_FAILURE ) ;
}
}
/*TODO: It may need to unmask the signal */
}
void rt_hw_context_switch ( rt_uint32_t from ,
rt_uint32_t to )
{
struct rt_thread * tid ;
pthread_t pid ;
thread_t * thread_from ;
thread_t * thread_to ;
RT_ASSERT ( from ! = to ) ;
#if 0
2025-07-05 19:47:28 +08:00
//TODO: <20> <> <EFBFBD> ܻ<EFBFBD> <DCBB> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> Ƕ<EFBFBD> <C7B6> <EFBFBD> л<EFBFBD> <D0BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2025-06-27 00:32:57 +08:00
if ( rt_thread_switch_interrupt_flag ! = 1 )
{
rt_thread_switch_interrupt_flag = 1 ;
// set rt_interrupt_from_thread
rt_interrupt_from_thread = * ( ( rt_uint32_t * ) from ) ;
}
# endif
pthread_mutex_lock ( ptr_int_mutex ) ;
rt_interrupt_from_thread = * ( ( rt_uint32_t * ) from ) ;
rt_interrupt_to_thread = * ( ( rt_uint32_t * ) to ) ;
2025-07-05 19:47:28 +08:00
/* <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֻ<EFBFBD> Dz<EFBFBD> <C7B2> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ִ<EFBFBD> <D6B4> <EFBFBD> жϴ<D0B6> <CFB4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֻ<EFBFBD> Ǽ<C7BC>
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> ж Ϲ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ־ λ
2025-06-27 00:32:57 +08:00
*/
cpu_pending_interrupts + + ;
pthread_mutex_unlock ( ptr_int_mutex ) ;
}
void rt_hw_context_switch_interrupt ( rt_uint32_t from ,
rt_uint32_t to )
{
rt_hw_context_switch ( from , to ) ;
}
void rt_hw_context_switch_to ( rt_uint32_t to )
{
//set to thread
rt_interrupt_to_thread = * ( ( rt_uint32_t * ) ( to ) ) ;
//clear from thread
rt_interrupt_from_thread = 0 ;
//set interrupt to 1
2025-07-05 19:47:28 +08:00
rt_thread_switch_interrupt_flag = 0 ; //TODO: <20> <> <EFBFBD> <EFBFBD> Ҫ<EFBFBD> <D2AA> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƕ<EFBFBD> <C7B6> <EFBFBD> л<EFBFBD> <D0BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2025-06-27 00:32:57 +08:00
/* enable interrupt
* note : NOW , there are only one interrupt in simposix : system tick */
rt_hw_interrupt_enable ( 0 ) ;
//start the main thread scheduler
mainthread_scheduler ( ) ;
//never reach here!
return ;
}
static int mainthread_scheduler ( void )
{
int i , res , sig ;
thread_t * thread_from ;
thread_t * thread_to ;
pthread_mutex_t mutex ;
pthread_mutexattr_t mutexattr ;
sigset_t sigmask , oldmask ;
/* save the main thread id */
mainthread_pid = pthread_self ( ) ;
TRACE ( " pid <%08x> mainthread \n " , ( unsigned int ) ( mainthread_pid ) ) ;
2025-07-05 19:47:28 +08:00
/* <20> <> <EFBFBD> <EFBFBD> suspend<6E> źź<C5BA> resume<6D> ź<EFBFBD> */
2025-06-27 00:32:57 +08:00
sigemptyset ( & sigmask ) ;
sigaddset ( & sigmask , MSG_SUSPEND ) ;
sigaddset ( & sigmask , MSG_RESUME ) ;
pthread_sigmask ( SIG_BLOCK , & sigmask , & oldmask ) ;
sigemptyset ( & sigmask ) ;
sigaddset ( & sigmask , SIGALRM ) ;
/* install signal handler of system tick */
signal_install ( SIGALRM , mthread_signal_tick ) ;
/* install signal handler used to suspend/resume threads */
signal_install ( MSG_SUSPEND , thread_suspend_signal_handler ) ;
signal_install ( MSG_RESUME , thread_resume_signal_handler ) ;
/* create a mutex and condition val, used to indicate interrupts occrue */
ptr_int_mutex = & mutex ;
pthread_mutexattr_init ( & mutexattr ) ;
pthread_mutexattr_settype ( & mutexattr , PTHREAD_MUTEX_RECURSIVE_NP ) ;
pthread_mutex_init ( ptr_int_mutex , & mutexattr ) ;
/* start timer */
start_sys_timer ( ) ;
thread_to = ( thread_t * ) rt_interrupt_to_thread ;
thread_resume ( thread_to ) ;
for ( ; ; )
{
# if 1
if ( sigwait ( & sigmask , & sig ) ! = 0 )
{
printf ( " mthread: sigwait get unexpected sig %d \n " , sig ) ;
}
# else
pause ( ) ;
# endif
TRACE ( " mthread:got sig %d \n " , sig ) ;
2025-07-05 19:47:28 +08:00
/* signal mask sigalrm <20> <> <EFBFBD> <EFBFBD> SIGALRM<52> ź<EFBFBD> */
2025-06-27 00:32:57 +08:00
pthread_sigmask ( SIG_BLOCK , & sigmask , & oldmask ) ;
// if (systick_signal_flag != 0)
if ( pthread_mutex_trylock ( ptr_int_mutex ) = = 0 )
{
tick_interrupt_isr ( ) ;
// systick_signal_flag = 0;
pthread_mutex_unlock ( ptr_int_mutex ) ;
}
else
{
TRACE ( " try lock failed. \n " ) ;
}
2025-07-05 19:47:28 +08:00
/* <20> <> <EFBFBD> <EFBFBD> SIGALRM<52> ź<EFBFBD> */
2025-06-27 00:32:57 +08:00
pthread_sigmask ( SIG_UNBLOCK , & sigmask , & oldmask ) ;
}
return 0 ;
}
/*
* Setup the systick timer to generate the tick interrupts at the required
* frequency .
*/
static void start_sys_timer ( void )
{
struct itimerval itimer , oitimer ;
int us ;
RT_ASSERT ( RT_TICK_PER_SECOND < = 1000000 | | RT_TICK_PER_SECOND > = 1 ) ;
us = 1000000 / RT_TICK_PER_SECOND - 1 ;
TRACE ( " start system tick! \n " ) ;
/* Initialise the structure with the current timer information. */
if ( 0 ! = getitimer ( TIMER_TYPE , & itimer ) )
{
TRACE ( " get timer failed. \n " ) ;
exit ( EXIT_FAILURE ) ;
}
/* Set the interval between timer events. */
itimer . it_interval . tv_sec = 0 ;
itimer . it_interval . tv_usec = us ;
/* Set the current count-down. */
itimer . it_value . tv_sec = 0 ;
itimer . it_value . tv_usec = us ;
/* Set-up the timer interrupt. */
if ( 0 ! = setitimer ( TIMER_TYPE , & itimer , & oitimer ) )
{
TRACE ( " set timer failed. \n " ) ;
exit ( EXIT_FAILURE ) ;
}
}
static void mthread_signal_tick ( int sig )
{
int res ;
pthread_t pid = pthread_self ( ) ;
if ( sig = = SIGALRM )
{
TRACE ( " pid <%x> signal: SIGALRM enter! \n " , ( unsigned int ) pid ) ;
//systick_signal_flag = 1;
TRACE ( " pid <%x> signal: SIGALRM leave! \n " , ( unsigned int ) pid ) ;
}
else
{
TRACE ( " got an unexpected signal <%d> \n " , sig ) ;
exit ( EXIT_FAILURE ) ;
}
}
/* isr return value: 1, should not be masked, if 0, can be masked */
static int tick_interrupt_isr ( void )
{
TRACE ( " isr: systick enter! \n " ) ;
/* enter interrupt */
rt_interrupt_enter ( ) ;
rt_tick_increase ( ) ;
/* leave interrupt */
rt_interrupt_leave ( ) ;
TRACE ( " isr: systick leave! \n " ) ;
return 0 ;
}