diff --git a/include/rtthread.h b/include/rtthread.h index b3d7ebd9497788aa5086a62c5b9bd509cd81422c..90426902128079762db886a737b6fee27bae1179 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -173,7 +173,8 @@ void rt_thread_inited_sethook (void (*hook)(rt_thread_t thread)); */ void rt_thread_idle_init(void); #if defined(RT_USING_HOOK) || defined(RT_USING_IDLE_HOOK) -void rt_thread_idle_sethook(void (*hook)(void)); +rt_err_t rt_thread_idle_sethook(void (*hook)(void)); +rt_err_t rt_thread_idle_delhook(void (*hook)(void)); #endif void rt_thread_idle_excute(void); rt_thread_t rt_thread_idle_gethandler(void); diff --git a/src/Kconfig b/src/Kconfig index 89f709478b981713e57b20f9e3a0c44483ae40b9..dc27e162f04bfc4e8e3d49439ad790171dd11819 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -75,6 +75,15 @@ config RT_USING_HOOK Enable the hook function when system running, such as idle thread hook, thread context switch etc. + if RT_USING_HOOK + config RT_IDEL_HOOK_LIST_SIZE + int "The max size of idel hook list" + default 4 + range 1 16 + help + The system has a hook list. This is the hook list size. + endif + config IDLE_THREAD_STACK_SIZE int "The stack size of idle thread" default 256 diff --git a/src/idle.c b/src/idle.c index f636d0fd4c3bd2e21211c258fecb09cd35805c21..d6c2f98a49f552f4799984c1b052e0aa932dbd30 100644 --- a/src/idle.c +++ b/src/idle.c @@ -26,6 +26,7 @@ * dead thread. * 2016-08-09 ArdaFu add method to get the handler of the idle thread. * 2018-02-07 Bernard lock scheduler to protect tid->cleanup. + * 2018-07-14 armink add idle hook list */ #include @@ -52,7 +53,12 @@ static rt_uint8_t rt_thread_stack[IDLE_THREAD_STACK_SIZE]; extern rt_list_t rt_thread_defunct; #ifdef RT_USING_IDLE_HOOK -static void (*rt_thread_idle_hook)(); + +#ifndef RT_IDEL_HOOK_LIST_SIZE +#define RT_IDEL_HOOK_LIST_SIZE 4 +#endif + +static void (*idle_hook_list[RT_IDEL_HOOK_LIST_SIZE])(); /** * @ingroup Hook @@ -61,12 +67,67 @@ static void (*rt_thread_idle_hook)(); * * @param hook the specified hook function * + * @return RT_EOK: set OK + * -RT_EFULL: hook list is full + * * @note the hook function must be simple and never be blocked or suspend. */ -void rt_thread_idle_sethook(void (*hook)(void)) +rt_err_t rt_thread_idle_sethook(void (*hook)(void)) { - rt_thread_idle_hook = hook; + rt_size_t i; + rt_base_t level; + rt_err_t ret = -RT_EFULL; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++) + { + if (idle_hook_list[i] == RT_NULL) + { + idle_hook_list[i] = hook; + ret = RT_EOK; + break; + } + } + /* enable interrupt */ + rt_hw_interrupt_enable(level); + + return ret; } + +/** + * delete the idle hook on hook list + * + * @param hook the specified hook function + * + * @return RT_EOK: delete OK + * -RT_ENOSYS: hook was not found + */ +rt_err_t rt_thread_idle_delhook(void (*hook)(void)) +{ + rt_size_t i; + rt_base_t level; + rt_err_t ret = -RT_ENOSYS; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++) + { + if (idle_hook_list[i] == hook) + { + idle_hook_list[i] = RT_NULL; + ret = RT_EOK; + break; + } + } + /* enable interrupt */ + rt_hw_interrupt_enable(level); + + return ret; +} + #endif /* Return whether there is defunctional thread to be deleted. */ @@ -174,12 +235,20 @@ void rt_thread_idle_excute(void) static void rt_thread_idle_entry(void *parameter) { +#ifdef RT_USING_IDLE_HOOK + rt_size_t i; +#endif + while (1) { + #ifdef RT_USING_IDLE_HOOK - if (rt_thread_idle_hook != RT_NULL) + for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++) { - rt_thread_idle_hook(); + if (idle_hook_list[i] != RT_NULL) + { + idle_hook_list[i](); + } } #endif