Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to analyze the $Sub$$main function in RT-Thread

2025-02-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces how to analyze the $Sub$main function in RT-Thread, the content is very detailed, interested friends can refer to, hope to be helpful to you.

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;}

The rtthread_startup function is divided into a subfunction:

1. Turn off the global interrupt

2. Board-level initialization rt_hw_board_init, in\ 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}

It was divided into several Mini Program.

The first function, NVIC__Configuration, sets the nested vector interrupt controller, which is also in\ bsp\ stm32f10x\ drivers\ board.c. No operation is done here, and then the static function of the same name will be used to initialize the interrupt controller of each peripheral.

/ * 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 VectorTable base location at 0x20000000 * / NVIC_SetVectorTable (NVIC_VectTab_RAM 0x0) # else / * VECT_TAB_FLASH * / / * Set the VectorTable base location at 0x08000000 * / NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x0); # endif

The second function, SysTick_Config, sets the system tick counter. The system tick counter is responsible for waking up rtt's thread scheduler, which is the "heartbeat" of the operating system.

The third function, rt_hw_usart_init, is responsible for initializing serial peripherals, which can initialize serial ports 1 to 4. This function is defined in\ bsp\ stm32f10x\ drivers\ usart.c. This function refers to the static function NVIC__Configuration in the same file, with the same name as the function in board.c, but with parameters. This function is responsible for setting the initialization of serial port interrupts.

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);}

The fourth function, rt_console_set_device, is defined in\ bsp\ stm32f10x\ drivers\ board.c. With instructions, you can see that it is the setting function of the console.

/ * 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 }

The fifth function, rt_components_board_init, is defined in\ bsp\ stm32f10x\ drivers\ components.c. Responsible for initializing board-level components.

/ * 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, print version information.

4. Rt_system_timer_init, initialize the system clock, which should be a date or something.

5. Rt_system_scheduler_init, initialize thread scheduler. I'll study this in detail later.

6. Rt_application_init, initializing the application thread, that is, the main thread. It is defined in\ bsp\ stm32f10x\ drivers\ components.c. Responsible for creating or initializing the main thread and then starting the main thread.

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);}

The definition of the system main thread is also in this file. And the $Super$$main function is in there.

/ * 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} this is the end of how to analyze the $Sub$main function in RT-Thread. I hope the above can be helpful and learn more. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report