__main() 和 main()(转载)

本文深入探讨了在嵌入式系统开发中,为何不应调用库函数__main(),并详细解释了其与系统初始化的潜在冲突。同时,文章提供了两种有效的替代方案,帮助开发者在做好初始化工作后顺利过渡至主应用程序。

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

__main() 和 main()(转载)

因为我们通常在BOOTLOADER中都已做好了比较细致的初始化工作,包括代码的搬运,所以我们最好别再调用库函数__main(),因为__main()作为ADS集成好的库函数,会对系统进行初始化设置,可能会与我们的初始化发生冲突,故在我们做好初始化后最好别调用__main()。仿真时若调了__main()且没设置entry会报警告,__main()库函数代码不太了解,估计跟ADS初始化有关,库函数__main()要慎用。

    当所有的系统初始化工作完成之后,就需要把程序流程转入主应用程序,即呼叫主应用程序。最简单的一种情况是:
    IMPORT   main
    B            main
   
    直接从启动代码跳转到应用程序的主函数入口,当然主函数名字可以由用户随便定义。
    在ARM ADS环境中,还另外提供了一套系统级的呼叫机制。
    IMPORT   __main
    B            __main
 
    __main()是编译系统提供的一个函数,负责完成库函数的初始化和初始化应用程序执行环境,最后自动跳转到main()。所以说,前者是库函数,后者就是我们自己编写的main()主函数;
 
    因此我们用的B __main其实是执行库函数,然后该库函数再调用我们的main() 函数,因此在单步调试时会看到先要跑一段程序(其实是库函数),然后再单步到我们自己的main函数(这个同时也说明如果有B __main 则就对应必须有main函数,否则编译出错),如果我们用 B main来进入我们的主函数的话,那在单步调试时就看到直接进入到我们自己的main函数了,中间不会看到其他程序;

    那么用B __main和用B main 这两这进入我们的main函数方式有什么不同呢?
    如果采用前者则会由编译器加入一段"段拷贝"程序,即我们说的从加载域到执行域转化程序;而采用后者就没有这个了,因此如果要进行 "段拷贝"只能自己动手编写程序来实现了,完成段拷贝后就可以进入我们的主函数了,当然这个主函数不一定是叫做main(),可以起个其他好听的名字,这个有别于使用B __main方式;不管采用哪种方式进入我们的程序,都要有一段"段拷贝"程序,跑完了段拷贝后才能可以进入我们主程序了!(顺便提一下:startup.s这个文件并没有所谓的"段拷贝"功能,再看也无益!)
 
    对含有启动程序来说,"执行地址与加载地址相同"不容易实现:
    如果执行地址与加载地址相同哪当然不需要做"段拷贝",但是个人理解编译器还会加入"段拷贝"程序(如果用B __main的话),只是因为条件不满足而不执行而已;但是对含有启动程序来说,"执行地址与加载地址相同"就不容易了.因为启动程序是要烧到非易失存储器里,用来在上电执行的,而这个程序必定会有RW段,如果RW放在非易失存储器,如FLASH,那就不好实现RW功能了,因此要给RW移动到能够实现RW功能的存储器,如SRAM等.因此,对含有启动程序来说,"执行地址与加载地址相同"就不容易实现;程序的入口点在C 库中的__main 处,在该点,库代码执行以下操作:

1. 将非零(只读和读写)运行区域从其载入地址复制到运行地址。
2. 清零ZI 区域。
3. 跳转到__rt_entry。
async/await 是 Python 3.5 引入的新语法,用于异步编程。它们的引入使得异步代码的编写更加简单易读。 async 定义一个协程(coroutine),它可以在运行过程中挂起并等待另一个协程的执行结果,类似于 JavaScript 中的 async/await。 await 则是等待一个异步操作的结果,这个异步操作可以是一个协程、一个 Future 对象或者其他可等待对象。在等待过程中,当前协程会被挂起,并让出 CPU,直到异步操作完成并返回结果。在 Python 3.5 之前的版本中,可以使用 yield from 来实现类似的功能,但是语法相对于 async/await 比较繁琐。 下面是一个简单的例子: ```python import asyncio async def foo(): print('start foo') await asyncio.sleep(1) # 等待 1 秒钟,模拟一个 IO 操作 print('end foo') async def bar(): print('start bar') await asyncio.sleep(2) # 等待 2 秒钟,模拟一个 IO 操作 print('end bar') async def main(): print('start main') await asyncio.gather(foo(), bar()) # 并发执行 foo bar print('end main') asyncio.run(main()) ``` 这个例子中,我们定义了三个协程 foo、bar main,其中 foo bar 分别模拟了一个 IO 操作,而 main 则并发执行了 foo bar,并等待它们的结果。输出结果如下: ``` start main start foo start bar end foo end bar end main ``` 可以看到,main 协程会等待 foo bar 协程的执行结果,但是在等待的过程中不会阻塞,而是让出 CPU 给其他协程执行。这样,整个程序的执行效率就得到了提升。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值