经历了各种曲折,终于把uCOS-III在M4上跑起来了,之前厂家寄错了板子,折腾了很久才发现折腾的IMX.6Q上根本没有M4核。
下面说下如何移植uCOS-III,以及目前的状态,和未来的工作。
如何移植:
目前Micrium公司已经提供了uCOS-III for IMX.6 solox的包,不过是用ARM -DS5来编译和下载的。考虑到没有DS5这个下载器,
估计也没法像freescale要到,所以就采用了arm-none-eabi-gcc配合u-boot的下载方式,以下是移植时修改的各个文件。
1 厂家提供的M4核跑的是MQX rtos,下面很多地方的移植是参考了mqx的代码,mqx结构分层很赞,稍微看一下就明白了。
2 去Micrium注册帐号,并且下载对应freescale厂家的Micrium-IMX6SX-SDB_OS3包
3 主要修改了启动文件startup.S,链接文件ram.ld,以及M4核所用到的UART2的波特率参数配置
startup.S
Reset_Handler:
ldr sp, =__SRAM_POOL_START @ set stack pointer.
@ Call the application's entry point.
LDR.W r0, =VectorTable
LDR.W r1, =#0xE000ED08 @ Set vector location
STR R0, [R1]
LDR.W R0, =#0xE000ED88 @ Enable CP10,CP11
LDR R1,[R0]
ORR R1,R1,#(0xF << 20)
STR R1,[R0]
LDR.W R0, =#0xE000EF34
LDR R1, [R0]
BIC R1, R1,#0x80000000 @ Disable FP registers save
BIC R1, R1,#0x40000000 @ Disable lazy stacking
STR R1,[R0]
bl main
bx lr
其中__SRAM_POOL_START定义于ram.ld里__SRAM_POOL_START = 0x1FFF8010,这个是M4所用到的256Kb的sram的前半段的
首地址偏移0x10位置
下面的几部分主要是设置中断向量表,时能CP10,CP11,FP相关的,就跳转到了main函数里
ram.ld
ENTRY(Reset_Handler)
EXTERN(main __vector_table ram_vector)
MEMORY
{
text (RX): ORIGIN = 0x00900000, LENGTH = 0x00020000 /* OCRAM */
data (RW): ORIGIN = 0x20000000, LENGTH = 0x00007E00 /* TCMU */
}
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
_estack = 0x00920000; /* end of 128K RAM */
CODE_BASE_ADDR_START = ORIGIN(text);
CODE_SIZE = LENGTH(text);
CODE_BASE_ADDR_END = CODE_BASE_ADDR_START + CODE_SIZE;
DATA_BASE_ADDR_START = ORIGIN(data);
DATA_SIZE = LENGTH(data);
DATA_BASE_ADDR_END = DATA_BASE_ADDR_START + DATA_SIZE;
/* exported symbols */
__DEFAULT_INTERRUPT_STACK_SIZE = 1024;
__ROM_END = CODE_BASE_ADDR_END;
/* 64kB of shared memory at DDR */
__SHARED_RAM_START = 0xBFF00000;
__SHARED_RAM_END = 0xBFF10000;
/* define 4KB clock management share memory in RAM*/
__SHARED_CM_IRAM_START = 0x2091F000;
__SHARED_CM_IRAM_END = 0x20920000;
/* 32kB TCML for system pool extension */
__SRAM_POOL_START = 0x1FFF8010; /* reserve first 4 word for reset (boot vector) */
__SRAM_POOL_END = 0x20000000;
__BOOT_STACK_ADDRESS = 0x20008000;
__KERNEL_DATA_END = DATA_BASE_ADDR_END;
SECTIONS
{
/* place vectors at the start, each section has only one symbol */
.vectors :
{
*(.vector)
} > text
/* place text */
.text :
{
*(KERNEL)
*(.text*)
*(.rodata*)
/* glue arm/thumb and thumb/arm code */
*(.glue_7)
*(.glue_7t)
/* unwind exception frame */
KEEP(*(.eh_frame))
KEEP(*(.eh_frame_hdr))
. = ALIGN(0x8);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
/* preinit_array */
__preinit_array_start = .;
KEEP (*(.preinit_array*))
__preinit_array_end = .;
/* init_array */
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
__init_array_end = .;
/* fini_array */
__fini_array_start = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
__fini_array_end = .;
/* gnu arm zero table */
. = ALIGN(4);
__zero_table_start__ = .;
LONG (_bss_start)
LONG (_bss_end - _bss_start)
__zero_table_end__ = .;
/* gnu arm copy table */
/* NOTE: bootloader requires rom to ram data copy */
. = ALIGN(4);
__copy_table_start__ = .;
LONG (LOADADDR(.data))
LONG (_data_start)
LONG (_data_end - _data_start)
__copy_table_end__ = .;
} > text
/* unwind exception frame */
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > text
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > text
/* place data, region address must be 8B aligned */
.data :
{
_data_start = .;
*(.vectors_ram)
*(.data*)
. = ALIGN(8);
_data_end = .;
} > data AT> text
/* place bss, section size must be 8 aligned because of startup */
.bss BLOCK(8) :
{
_bss_start = .;
*(.bss*)
*(COMMON)
. = ALIGN(8);
_bss_end = .;
} > data
._user_heap_stack :
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} > data
.kernel_data BLOCK(0x10) :
{
__KERNEL_DATA_START = ALIGN(0x10);
} > data
__cs3_heap_end = .;
}
考虑到后面还要移植mcc,dma等,所以就沿用了mqx里的ram.ld,基本没做多大改动。
bsp_ser.c
void BSP_Ser_Init (void)
{
/* ----------------- INIT OS OBJECTS ------------------ */
BSP_OS_SemCreate(&BSP_SerTxWait, 0, "Serial Tx Wait");
BSP_OS_SemCreate(&BSP_SerRxWait, 0, "Serial Rx Wait");
BSP_OS_SemCreate(&BSP_SerLock, 1, "Serial Lock");
/* IOMUXC configuration for the IMX6Q-SDB */
DEF_BIT_FIELD_WR(IMX6_IOMUXC_MUX_CTL_GPIO1_IO06, 0x0, DEF_BIT_FIELD(3u, 0u));
DEF_BIT_FIELD_WR(IMX6_IOMUXC_MUX_CTL_UART2_URDSI, 0x0, DEF_BIT_FIELD(2u, 0u));
DEF_BIT_FIELD_WR(IMX6_IOMUXC_MUX_CTL_GPIO1_IO07, 0x0, DEF_BIT_FIELD(3u, 0u));
DEF_BIT_FIELD_WR(IMX6_IOMUXC_MUX_CTL_UART2_URDSI, 0x0, DEF_BIT_FIELD(2u, 0u));
IMX6_IOMUXC_MUX_PAD_GPIO1_IO06 = 0x1B0B0;
IMX6_IOMUXC_MUX_PAD_GPIO1_IO07 = 0x1B0B0;
DEF_BIT_FIELD_WR(IMX6_UART_UART2_UFCR, 0x5, DEF_BIT_FIELD(3u, 7u)); /* Divide by 1. */
IMX6_UART_UART2_UCR2 = 0;
DEF_BIT_SET(IMX6_UART_UART2_UCR2, DEF_BIT_05); /* 8 bit word size. */
IMX6_UART_UART2_UCR3 = DEF_BIT_02;
IMX6_UART_UART2_UCR1 = DEF_BIT_00;
DEF_BIT_SET(IMX6_UART_UART2_UCR2, DEF_BIT_14); /* Ignore CTS. */
DEF_BIT_SET(IMX6_UART_UART2_UCR2, DEF_BIT_01); /* Enable RX. */
DEF_BIT_SET(IMX6_UART_UART2_UCR2, DEF_BIT_02); /* Enable TX. */
DEF_BIT_SET(IMX6_UART_UART2_UCR2, DEF_BIT_00); /* De-assert reset. */
/* Default configuration for 115200 at 24Mhz ref clock. */
IMX6_UART_UART2_UBIR = 3845u;//1151
IMX6_UART_UART2_UBMR = 49999u;
}
主要修改了波特率的设置,之前M4打印的数据总是乱码,起初怀疑M4这边的一些时钟没有打开或者参数配的有问题,找了很久也没看到设置
时钟的地方,后来偶然间看了链接文件ram.ld里的__SHARED_CM_IRAM_START地址,发现有些控制器的配置是在U-Boot里做的,M4这边只是读取
配置结果来用。然后在U-boot下执行clock命令,得到UART的时钟是24000000,重新修改了下IMX6_UART_UART2_UBIR = 3845u;//1151就正常出
log了。
目前状态:
目前gcc版本的uCOS-III在M4下跑的还比较稳定,测试几天了还没有挂起的。用U-boot来加载M4核启动的命令如下:
tftpboot 900000 uCOS-III.bin
bootaux 900000
第一条是通过tftpboot命令把pc上编译出来的uCOS-III.bin加载到ram.ld里0x00900000地址处
第二条命令是使用u-boot的bootaux命令来启动uCOS-III,其实核心是使能了M4的时钟。
uCOS-III跑起来的状态就是隔5秒打印一下
Application start on the Cortex-M4!
Periodic output from the Cortex-M4
Periodic output from the Cortex-M4
Periodic output from the Cortex-M4
...
后续工作:
下一步就要移植mcc和一些基于mcc通讯的例子,以及DMA部分了,目前考虑的是将spi flash的内容以DMA方式读出,然后通过mcc通道传给linux那端
进行打印显示。
|
|