一、C语言运行环境构建
1、设置处理器模式
6ULL开发指南第六章。 设置6ULL处于SVC模式下,共有9种模式。通过CPSR寄存器设置,设置GPSR寄存器的bit4-0,也就是M[4:0]为10011=0x13。读写状态寄存器需要用到MRS和MSR指令。MRS将CPSR寄存器书局读取到通用寄存器里面,MSR指令将通过寄存器的值写到CPSR寄存器里面去。
2、设置SP指针
SP可以指向内部RAM,也可以指向DDR,我们将其指向DDR。SP设置到哪里?512MB
的范围0x80000000-0x9FFFFFFF。栈大小0x200000=2MB。处理器栈增长方式,对于A7而
言是向下增长的。设置sp指向 0x80200000。
3、跳转到C语言
使用b指令,跳转到C语言函数,比如main函数。
4、编写程序
在Board_Drivers中创建文件夹2_ledc,在VSCODE中打开这个文件夹,另存工作区到2_ledc命名为ledc,再新建一个文件start.s。
恩智浦处理器的.bin文件头部已经将DDR初始化处理好了,所以这里只用了
LDR SP,=0x80200000一行代码就行了,如果使用了其他处理器,一定要看处理器的启动方式,如果其无法自己初始化DDR,那么得自己手动初始化。
新建main.c文件
创建.h
编写Makefile
烧录:
闪烁:
#include <stdio.h>
#include "main.h"
//使能外设时钟
void clk_enable()
{
CCM_CCGR0 = 0xFFFFFFFF;
CCM_CCGR1 = 0xFFFFFFFF;
CCM_CCGR2 = 0xFFFFFFFF;
CCM_CCGR3 = 0xFFFFFFFF;
CCM_CCGR4 = 0xFFFFFFFF;
CCM_CCGR5 = 0xFFFFFFFF;
CCM_CCGR6 = 0xFFFFFFFF;
}
// 初始化LED
void led_init()
{
SW_MUX_GPIO1_IO03 = 0x5; //复用GPIO1_IO03为GPIO
SW_PAD_GPIO1_IO03 = 0x10B0; //设置GPIO1_IO03的电气属性
//GPIO 初始化
GPIO1_GDIR = 0x8; //设置为输出功能
GPIO1_DR = 0x0; //输出低电平
}
//短延时
void delay_short(volatile unsigned int n)
{
while(n--){}
}
//延时,一次大概是1ms,在主频为396Mhz时
void delay(volatile unsigned int n)
{
while(n--)
{
delay_short(0x7ff);
}
}
void led_on(void)
{
GPIO1_DR &= ~(1<<3); //bit3清0
}
void led_off(void)
{
GPIO1_DR |= ~(1<<3); //bit3 1
}
int main(void)
{
/* 初始化LED */
/* 设置LED 闪烁*/
clk_enable(); //使能外设时钟
led_init();
while(1)
{
led_on();
delay(500);
led_off();
delay(500);
}
return 0;
}
二、链接脚本
链接脚本描述了要连接的文件,以及链接顺序,和链接首地址。指南10.4
创建脚本文件
SECTIONS{
. = 0X87800000; //链接首地址
.text :
{
start.o
*(.text) //表示剩下的所有代码段,重点是start.o一定要放到前面去链接
}
.rodata ALIGN(4) : { *(.rodata) } //ALING(4) 对这个段进行四字节对齐 .rodata数据段
.data ALIGN(4) : { *(.data) } //这个段所有的数据都放到.data里面去
__bss_star=.;
.bss ALIGN(4) : {*(.bss) *(commom)}
__bss_end=.;
}
运用连接脚本之后,可以用-O2(优化)