您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何分析RT-Thread中的$Sub$main函數(shù),內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
int rtthread_startup(void) { rt_hw_interrupt_disable(); /* board level initialization * NOTE: please initialize heap inside board initialization. */ rt_hw_board_init(); /* show RT-Thread version */ rt_show_version(); /* timer system initialization */ rt_system_timer_init(); /* scheduler system initialization */ rt_system_scheduler_init(); #ifdef RT_USING_SIGNALS /* signal system initialization */ rt_system_signal_init(); #endif /* create init_thread */ rt_application_init(); /* timer thread initialization */ rt_system_timer_thread_init(); /* idle thread initialization */ rt_thread_idle_init(); #ifdef RT_USING_SMP rt_hw_spin_lock(&_cpus_lock); #endif /*RT_USING_SMP*/ /* start scheduler */ rt_system_scheduler_start(); /* never reach here */ return 0; }
rtthread_startup函數(shù)又分了是一個子函數(shù):
1、關全局中斷
2、板級初始化rt_hw_board_init,在\bsp\stm32f10x\drivers\board.c中。
/** * This function will initial STM32 board. */ void rt_hw_board_init(void) { /* NVIC Configuration */ NVIC_Configuration(); /* Configure the SysTick */ SysTick_Config( SystemCoreClock / RT_TICK_PER_SECOND ); #if STM32_EXT_SRAM EXT_SRAM_Configuration(); #endif rt_hw_usart_init(); rt_console_set_device(RT_CONSOLE_DEVICE_NAME); #ifdef RT_USING_COMPONENTS_INIT rt_components_board_init(); #endif }
又分成了好幾個小程序。
第一個函數(shù)NVIC__Configuration設置嵌套向量中斷控制器,也在\bsp\stm32f10x\drivers\board.c里。這里先不做操作,后面會用到這個函數(shù)的同名靜態(tài)函數(shù)來初始化各個外設的中斷控制器。
/******************************************************************************* * Function Name : NVIC_Configuration * Description : Configures Vector Table base location. * Input : None * Output : None * Return : None *******************************************************************************/ void NVIC_Configuration(void) { #ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif
第二個函數(shù)SysTick_Config設置了系統(tǒng)滴答計數(shù)器。系統(tǒng)滴答計數(shù)器負責喚醒rtt的線程調度器,也就是操作系統(tǒng)的“心跳”。
第三個函數(shù)rt_hw_usart_init負責初始化串口外設,可以初始化串口1到4。這個函數(shù)定義在\bsp\stm32f10x\drivers\usart.c中。這個函數(shù)引用了同文件里的靜態(tài)函數(shù)NVIC__Configuration,與board.c里的函數(shù)同名,但是含參。這個函數(shù)負責設置串口中斷的初始化。
void rt_hw_usart_init(void) { struct stm32_uart* uart; struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; RCC_Configuration(); GPIO_Configuration(); #if defined(RT_USING_UART1) uart = &uart1; config.baud_rate = BAUD_RATE_115200; serial1.ops = &stm32_uart_ops; serial1.config = config; NVIC_Configuration(uart); /* register UART1 device */ rt_hw_serial_register(&serial1, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_DMA_RX, uart); #endif /* RT_USING_UART1 */ #if defined(RT_USING_UART2) uart = &uart2; config.baud_rate = BAUD_RATE_115200; serial2.ops = &stm32_uart_ops; serial2.config = config; NVIC_Configuration(uart); /* register UART2 device */ rt_hw_serial_register(&serial2, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_DMA_RX, uart); #endif /* RT_USING_UART2 */ #if defined(RT_USING_UART3) uart = &uart3; config.baud_rate = BAUD_RATE_115200; serial3.ops = &stm32_uart_ops; serial3.config = config; NVIC_Configuration(uart); /* register UART3 device */ rt_hw_serial_register(&serial3, "uart3", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_DMA_RX, uart); #endif /* RT_USING_UART3 */ #if defined(RT_USING_UART4) uart = &uart4; config.baud_rate = BAUD_RATE_115200; serial4.ops = &stm32_uart_ops; serial4.config = config; NVIC_Configuration(uart); /* register UART4 device */ rt_hw_serial_register(&serial4, "uart4", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_DMA_RX, uart); #endif /* RT_USING_UART4 */ }
static void NVIC_Configuration(struct stm32_uart* uart) { NVIC_InitTypeDef NVIC_InitStructure; /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = uart->irq; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
第四個函數(shù)rt_console_set_device定義在\bsp\stm32f10x\drivers\board.c里。有說明,可以看出是控制臺的設置函數(shù)。
/** * This function will set a device as console device. * After set a device to console, all output of rt_kprintf will be * redirected to this new device. * * @param name the name of new console device * * @return the old console device handler */ rt_device_t rt_console_set_device(const char *name) { rt_device_t new, old; /* save old device */ old = _console_device; /* find new console device */ new = rt_device_find(name); if (new != RT_NULL) { if (_console_device != RT_NULL) { /* close old console device */ rt_device_close(_console_device); } /* set new console device */ rt_device_open(new, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_STREAM); _console_device = new; } return old; }
第五個函數(shù)rt_components_board_init定義在\bsp\stm32f10x\drivers\components.c里。負責初始化板級組件。
/** * RT-Thread Components Initialization for board */ void rt_components_board_init(void) { #if RT_DEBUG_INIT int result; const struct rt_init_desc *desc; for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++) { rt_kprintf("initialize %s", desc->fn_name); result = desc->fn(); rt_kprintf(":%d done\n", result); } #else const init_fn_t *fn_ptr; for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++) { (*fn_ptr)(); } #endif }
3、rt_show_version,打印版本信息。
4、rt_system_timer_init,初始化系統(tǒng)時鐘,應該是日期什么的。
5、rt_system_scheduler_init,初始化線程調度器。這個以后詳細學習。
6、rt_application_init,初始化應用線程,也就是主線程。定義在\bsp\stm32f10x\drivers\components.c里。負責創(chuàng)建或初始化主線程,然后啟動主線程。
void rt_application_init(void) { rt_thread_t tid; #ifdef RT_USING_HEAP tid = rt_thread_create("main", main_thread_entry, RT_NULL, RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20); RT_ASSERT(tid != RT_NULL); #else rt_err_t result; tid = &main_thread; result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL, main_stack, sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20); RT_ASSERT(result == RT_EOK); /* if not define RT_USING_HEAP, using to eliminate the warning */ (void)result; #endif rt_thread_startup(tid); }
系統(tǒng)主線程的定義也在這個文件里。而$Super$$main函數(shù)就在這里面了。
/* the system main thread */ void main_thread_entry(void *parameter) { extern int main(void); extern int $Super$$main(void); /* RT-Thread components initialization */ rt_components_init(); #ifdef RT_USING_SMP rt_hw_secondary_cpu_up(); #endif /* invoke system main function */ #if defined(__CC_ARM) || defined(__CLANG_ARM) $Super$$main(); /* for ARMCC. */ #elif defined(__ICCARM__) || defined(__GNUC__) main(); #endif }
關于如何分析RT-Thread中的$Sub$main函數(shù)就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。