1.汇编难写,选择C。
2.为IMX创造C环境: start.s
_start:
/* 进入 SVC 模式 */
mrs r0, cpsr
bic r0, r0, #0x1f /* 将 r0 的低 5 位清零,也就是 cpsr 的 M0~M4 */
orr r0, r0, #0x13 /* r0 或上 0x13,表示使用 SVC 模式
msr cpsr, r0 /* 将 r0 的数据写入到 cpsr_c 中 */
ldr sp, =0X80200000 /* 设置栈指针 */
b main /* 跳转到 main 函数 */
IMX有9种模式,目前选用SVC(超级管理员模式,特权模式,供操作系统使用。) arm运行模式在16个内核寄存器组的CPSR寄存器控制。开发板上的DDR3的地址范围是0x80000000 - 0xA0000000 , 这里设置了SP指针为0x80200000 , 由于指针是向下增长的, 于是0x80200000 - 0x80000000 = 0x200000 = 2MB ,于是SVC的栈大小为2M。
链接脚本
链接脚本是.lds文件 。
当所有.c文件变成.o文件后,需要.o文件链接到以0x87800000为起始地址的区域,
所有文件都是链接到0x87800000为起始的区域。但是文件多的话,有的文件想安排在自己想链接的地址处,就需要链接脚本了。
SECTIONS{
. = 0X87800000;
.text :
{
start.o
main.o
*(.text)
}
.rodata ALIGN(4) : {*(.rodata*)}
.data ALIGN(4) : { *(.data) }
__bss_start = .;
.bss ALIGN(4) : { *(.bss) *(COMMON) }
__bss_end = .;
}
这个链接脚本先定义了起始链接脚本地址 . 为0x87800000 , 然后定义了一个
text段里面按顺序排了start.0 , main.o ,*(.text) 。后面是四字节对齐(起始地址整除4)。
__bss_start和 __bss_end 记录了BSS段(定义了但没初始化的变量)的起始和结束地址,到时候需要自己把这段里的数据全部清0 。MDK会把自己申请但没赋值的变量定为0 , 但IMX需要自己来。
有了链接脚本后,makefile就从arm-linux-gnueabihf-ld -Ttext 0X87800000 -o ledc.elf ^
即使上面已经实现了C语言环境,但是STm32的习惯还在,可以把IMX编程方式改为STM32。
NXP为IMX6Ul编写了类似的SDK库,但只有IMX6UL有,所以以后用到别的Cortex-A芯片需要自己写这个库。具体移植我看的正点原子。
有两个函数:
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0);
IOMUXC_SetPinMux 是 用 来 设 置 IO 复 用 功 能 的,其实这个函数输入是6个变量,但IOMUXC_GPIO1_IO03_GPIO1_IO03是个宏定义,是5个变量的宏定义,最后一个0所在的功能是IO软件输入使能,这里是0不使能即用输出
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0X10B0);
函数 IOMUXC_SetPinConfig 设置的是 IO 的上下拉、速度等的,这个的IOMUXC_GPIO1_IO03_GPIO1_IO03也是个宏定义代表了5个变量,最后一个0x10B0是写入IO 配置寄存器为 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03的值,就是设置GPIO的属性。
网友评论