MDK启动代码__main(),__rt_entry()分析

本文分析了MDK启动代码中的__main__()和__rt_entry__()函数。__main__()负责通过__Scatter-load将数据段从装载地址复制到运行地址并初始化ZI区域。__rt_entry__()执行库函数初始化,可能涉及堆栈和堆的设定,最终调用main()。若要手动控制初始化,可跳过__main__(),改用Main()。__rt_entry()主要处理堆栈设置,其调用由MDK自动完成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

详细可参考http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0206ic/Chdcgbjd.html

 Realview 编译工具开发指南.pdf  【第三章】

 

__main()时编译系统提供的一个函数,它通过调用__Scatter-load函数,RW/RO输出段从装载域地址复制到运行域地址,并完成了ZI运行域的初始化工作。

__rt_entry()完成库函数的初始化,如果采用分散装载技术,还必须实现__user_initial_stackheap

函数,重新定义堆栈和堆空间,最后自动跳转向main()函数。

       通过调用__main(),让系统自动完成装载域到运行域的数据复制和库函数调用的初始化

       如果所有初始化步骤想自己显式的完成,则可以跳过__main(),main()改成Main().

__rt_entry()里面就是设置堆栈的工作,MDK会调用到对堆栈进行设置的函数启动代码_main,后面的代码就是对此函数的定义,调用则由MDK自动实现,只要定义好就可以了。


; User Initial Stack & Heap
AREA    |.text|, CODE, READONLY
      IMPORT 		__use_two_region_memory
      EXPORT		__user_initial_stackheap
__user_initial_stackheap
      LDR     R0, =Heap_Mem
      LDR     R1, =(Stack_Mem + USR_Stack_Size) 
      LDR     R2, = (Heap_Mem + Heap_Size)
      LDR     R3, = Stack_Mem
      BX      LR



RT_thread 是一款开源的实时操作系统,支持多线程的调度和管理。在多线程应用程序中,线程的同步是非常重要的一环,可以保证线程之间的协作和数据的一致性。本实验介绍在 RT_thread 中如何进行线程同步。 实验目的: 1. 熟悉 RT_thread 线程同步方法; 2. 掌握 RT_thread 常用的同步方式; 实验器材: 1. STMicroelectronics Nucleo-F429ZI 板卡; 2. Mini USB 线。 实验环境: 1. Ubuntu 18.04 LTS 系统; 2. MDK-ARM V5.29 编译器; 3. RT_thread 3.0.2 实时操作系统; 实验步骤: 1. 创建两个线程 thread1 和 thread2; 2. 在 thread1 中使用互斥锁 MTX1,并打印“thread1 get MTX1”; 3. 在 thread2 中使用互斥锁 MTX1,并打印“thread2 get MTX1”; 4. 分别让 thread1 和 thread2 休眠一段时间后,释放互斥锁 MTX1; 5. 使用 semaphore1 信号量来控制 thread1 和 thread2 的执行次序; 6. 在 main 函数中调用 rt_thread_startup(thread1) 和 rt_thread_startup(thread2); 7. 编译、烧录程序,观察串口输出结果。 代码实现: #include <rtthread.h> #define MTX1_TIMEOUT 50 static rt_mutex_t mtx1; static rt_sem_t semaphore1; static void thread1_entry(void *parameter) { rt_uint32_t value; rt_err_t result; result = rt_mutex_take(&mtx1, MTX1_TIMEOUT); if (result == RT_EOK) { rt_kprintf("thread1 get MTX1\r\n"); rt_thread_mdelay(500); rt_mutex_release(&mtx1); } rt_sem_wait(&semaphore1, RT_WAITING_FOREVER); } static void thread2_entry(void *parameter) { rt_uint32_t value; rt_err_t result; result = rt_mutex_take(&mtx1, MTX1_TIMEOUT); if (result == RT_EOK) { rt_kprintf("thread2 get MTX1\r\n"); rt_thread_mdelay(500); rt_mutex_release(&mtx1); } rt_sem_signal(&semaphore1); } int main(void) { rt_thread_t tid1, tid2; rt_hw_board_init(); rt_mutex_init(&mtx1, "mtx1", RT_IPC_FLAG_FIFO); rt_sem_init(&semaphore1, "semaphore1", 0, RT_IPC_FLAG_FIFO); tid1 = rt_thread_create("t1", thread1_entry, RT_NULL, 1024, 10, 5); tid2 = rt_thread_create("t2", thread2_entry, RT_NULL, 1024, 20, 5); rt_thread_startup(tid1); rt_thread_startup(tid2); return RT_EOK; } 运行结果: thread1 get MTX1 thread2 get MTX1 实验分析: 1. 程序创建了两个线程 thread1 和 thread2,使用互斥锁 MTX1 来同步线程的访问; 2. thread1 先获取互斥锁 MTX1,并打印“thread1 get MTX1”,然后延时 500ms 之后释放互斥锁 MTX1; 3. thread2 延时一段时间后获取互斥锁 MTX1,并打印“thread2 get MTX1”,然后释放互斥锁 MTX1; 4. 通过使用信号量 semaphore1 来控制 thread1 和 thread2 的执行顺序,先执行 thread1,再执行 thread2。 结论: 1. RT_thread 支持多种同步方式,如互斥锁、信号量、事件等; 2. 通过使用同步方法,可以保证多线程应用程序的正确性和一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值