Arm中main()和_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。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`arm_cfft_f32` 是 ARM CMSIS-DSP 库用于实现快速傅里叶变换的函数,可以用于对实数或复数序列进行离散傅里叶变换(DFT)。 以下是 `arm_cfft_f32` 函数的函数原型: ```c void arm_cfft_f32(const arm_cfft_instance_f32 *S, float32_t *p1, uint8_t ifftFlag, uint8_t bitReverseFlag); ``` 其: - `S`:指向 `arm_cfft_instance_f32` 结构体的指针,该结构体包含了傅里叶变换所需的参数,需要在调用函数前初始化。 - `p1`:指向存储 DFT 输入和输出数据的数组的指针。 - `ifftFlag`:表示是否进行反向快速傅里叶变换(IFFT)的标志。如果为 0,则进行正向傅里叶变换(FFT)。如果为非 0 值,则进行 IFFT。 - `bitReverseFlag`:表示是否进行位倒序的标志。如果为 0,则不进行位倒序。如果为非 0 值,则进行位倒序。 以下是一个使用 `arm_cfft_f32` 函数进行 FFT 的示例代码: ```c #include "arm_math.h" #define FFT_SIZE 1024 // 定义输入和输出缓冲区 float32_t fft_input[FFT_SIZE]; float32_t fft_output[FFT_SIZE]; // 定义 FFT 变换参数 arm_cfft_instance_f32 fft_inst; uint32_t fft_size_log2 = 10; // FFT 大小为 2^10 = 1024 uint8_t ifft_flag = 0; // 进行正向 FFT uint8_t bit_reverse_flag = 1; // 进行位倒序 int main(void) { // 初始化 FFT 变换参数 arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, ifft_flag, bit_reverse_flag); // 填充输入数据 for (uint32_t i = 0; i < FFT_SIZE; i++) { fft_input[i] = sinf(2 * PI * i / FFT_SIZE); } // 进行 FFT 变换 arm_cfft_f32(&fft_inst, fft_input, ifft_flag, bit_reverse_flag); // 处理 FFT 输出数据 // ... while (1) { // 主循环 } } ``` 在上述示例代码,首先定义了输入和输出缓冲区,以及 FFT 变换的参数。然后通过 `arm_cfft_radix4_init_f32` 函数初始化 `fft_inst` 参数。接着填充输入数据,并通过 `arm_cfft_f32` 函数进行 FFT 变换。最后可以对 FFT 输出数据进行处理。注意,FFT 的输出数据在 `fft_input` 数组,但是需要进行格式转换才能得到正确的结果。具体的格式转换方法可以参考 ARM CMSIS-DSP 库的文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值