Nuttx移植到S5PV210

        最近没有分析飞控的代码,转而研究Nuttx实时操作系统的移植。入门一个操作的移植还是挺有难度的,首先代码的框架能理清楚就很不容易了,尤其是Nuttx这种相对小众的操作系统,参考资料比较少,中文资料更少。

        因为目的是学习Nuttx的移植,所以不想简单地用pixhawk飞控作为开发板来实验,那样的话总是会局限在现有的代码中。正好手头有块飞凌的开发板,对s5pv210这款mcu又比较熟悉了,避免了学习硬件的麻烦。

        从零开始移植到一款新的mcu难度还是挺大的,所以最好在现有的代码中找到一款跟自己使用的相似的作为参考的对象。我就选择了am335x作为依据,先分析下Nuttx的代码结构,和针对am335x需要改的代码。

      移植主要关注三个文件夹,即arch\arm\src\am335x   arch\arm\src\armv7-a 和  boards\arm\am335x\beaglebone-black三个文件夹。第一个文件夹主要负责am335x的gpio,i2c,irq等片上外设的初始化。第二个文件夹主要负责mmu和运行环境等的初始化。第三个文件夹主要就是开发板相关的初始化了,包括按钮、led、lcd等的外设的初始化。

arch\arm\src\armv7-a文件夹中的arm_head.S文件的_start函数是整个程序的入口函数。下面贴出_start函数的开始的实现:

	mov		r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT)
	msr		cpsr_c, r0

	//关闭mmu和cache

	mrc		CP15_SCTLR(r0)
	bic		r0, r0, #(SCTLR_M | SCTLR_C)
	bic		r0, r0, #(SCTLR_I)
	mcr		CP15_SCTLR(r0)

	//清除页表

	ldr		r5, .LCppgtable			/* r5=phys. page table */
#ifndef CONFIG_ARCH_ROMPGTABLE
	mov		r0, r5
	mov		r1, #0
	add		r2, r0, #PGTABLE_SIZE
.Lpgtableclear:
	str		r1, [r0], #4
	str		r1, [r0], #4
	str		r1, [r0], #4
	str		r1, [r0], #4
	teq		r0, r2
	bne		.Lpgtableclear

#ifdef ARMV7A_PGTABLE_MAPPING
	/* If the page table does not lie in the same address space as does the
	 * mapped RAM in either case.  So we will need to create a special
	 * mapping for the page table.
	 *
	 * Load information needed to map the page table.  After the ldmia, we
	 * will have
	 *
	 *   R1 = The aligned, physical base address of the page table
	 *   R2 = The aligned, virtual base address of the page table
	 *   R3 = The MMU flags to use with the .text space mapping
	 *   R5 = The physical address of the L1 page table (from above)
	 *
	 * The value in R1 could have been obtained by simply masking R5.
	 */
    //加载LCptinfo地址
	adr		r0, .LCptinfo			/* Address of page table description */
	ldmia	r0, {r1, r2, r3}		/* Load the page table description */

	/* A single page is sufficient to map the page table */

	orr		r0, r1, r3				/* OR MMU flags into physical address */
	str		r0, [r5, r2, lsr #18]	/* Map using the virtual address as an index */
#endif

	/* Load information needed to map the .text region.  After the ldmia, we
	 * will have:
	 *
	 *   R1 = Aligned, physical address of the start of the .text region
	 *   R2 = Aligned, virtual address of the start of the .text region
	 *   R3 = MMU flags associated with the .txt region
	 *   R4 = The number of 1MB sections in the mapping
	 *   R5 = The physical address of the L1 page table (from above)
	 */






    //加载textinfo地址
	adr		r0, .LCtextinfo			/* Address of text info */
	ldmia	r0, {r1, r2, r3, r4}	/* Load the text description */

#ifndef CONFIG_IDENTITY_TEXTMAP
	/* Create identity mapping for first MB of the .text section to support
	 * this start-up logic executing out of the physical address space.  This
	 * identity mapping will be removed by .Lvstart (see below).  Of course,
	 * we would only do this if the physical-virtual mapping is not already
	 * the identity mapping.
	 */

	orr		r0, r1, r3				/* OR MMU flags into physical address */
	str		r0, [r5, r1, lsr #18]	/* Identity mapping */
#endif

	/* Map the entire .text region.  We do this before enabling caches so
	 * we know that the data will be in place in the data cache.  We map the
	 * entire text region because we don't know which parts are needed for
	 * start-up.
	 *
	 * The page table base address is in R5.  Each 32-bit page table entry
	 * maps 1 MB of address space and is indexed by the lower 20 bits of
	 * the virtual address in R2
	 */

	add		r2, r5, r2, lsr #18		/* R2=Offset page table address */

	/* Now loop until each page table entry has been written for the .text
	 * region.
	 */

.Lpgtextloop:
	orr		r0, r1, r3				/* R0: OR MMU flags into physical address */
	subs	r4, r4, #1				/* R4: Decrement the section count */
	str		r0, [r2], #4			/* Save page table entry, increment page table address */
	add		r1, r1, #(1024*1024)	/* R1: Increment the physical address */
	bne		.Lpgtextloop			/* Loop while R4 is non-zero */

#if defined(CONFIG_BOOT_RUNFROMFLASH) && !defined(CONFIG_BOOT_SDRAM_DATA)
	/* If we are executing from FLASH, then we will need additional mappings for
	 * the primary RAM region that holds the .data, .bss, stack, and heap memory.
	 *
	 *   Here we expect to have:
	 *   r5 = Address of the base of the L1 table
	 *
	 * Load information needed to map the .text region.  After the ldmia, we
	 * will have:
	 *
	 *   R1 = Aligned, physical address of the start of the .text region
	 *   R2 = Aligned, virtual address of the start of the .text region
	 *   R3 = MMU flags associated with the .txt region
	 *   R4 = The number of 1MB sections in the mapping
	 *   R5 = The physical address of the L1 page table (from above)
	 */



//加载LCraminfo地址
	adr		r0, .LCraminfo			/* Address of primary RAM info */
	ldmia	r0, {r1, r2, r3, r4}	/* Load the primary RAM description */
	add		r2, r5, r2, lsr #18		/* R2=Offset page table address */

	/* Loop until each page table entry has been written for the primary RAM
	 * region.
	 */

.Lpgramloop:
	orr		r0, r1, r3				/* R0: OR MMU flags into physical address */
	subs	r4, r4, #1				/* R4: Decrement the section count */
	str		r0, [r2], #4			/* Save page table entry, increment page table address */
	add		r1, r1, #(1024*1024)	/* R1: Increment the physical address */
	bne		.Lpgramloop				/* Loop while R4 is non-zero */

#endif /* CONFIG_BOOT_RUNFROMFLASH && !CONFIG_BOOT_SDRAM_DATA */
#endif /* CONFIG_ARCH_ROMPGTABLE */

其中的LCppgtable、LCptinfo、LCtextinfo、LCraminfo在后面都有定义,这里我整理出来

LCppgtable->待整理

LCptinfo->PGTABLE_BASE_PADDR和PGTABLE_BASE_VADDR->AM335X_OCMCO_PADDR和AM335X_0CMC0_VADDR->(AM335X_0CMC0_PSECTION+AM335X_0CMC0_OFFSET)->(0X40300000+0X00000000)

LCtextinfo->NUTTX_TEXT_PADDR和NUTTX_TEXT_VADDR->(CONFIG_RAM_START&0XFFF00000)->(0X8a000000&0xfff00000)

LCraminfo->NUTTX_RAM_PADDR和NUTTX_RAM_VADDR->

arm_head.S文件主要完成内存相关的初始化后,接着就是bl arm_data_initialize和bl arm_boot完成其它的初始化。

 

 

arch\arm\src\am335x文件夹中的内容都是跟mcu相关的,很多很细的东西,现在暂时不分析,等到移植成功后再分析。

 

boards\arm\am335x\beaglebone-black文件夹中,

       configs下lcd和nsh分别都有一个defconfig文件,该文件是在make config时的配置文件,根据选择的不同的模式会复制对应的defconfig文件到.config文件中。

       include文件夹中主要是board.h文件。该文件定义了led和button的引脚。

       scripts文件夹中有Make.defs和sdram.ld文件。由名称可知,分别是makefile文件和链接脚本文件。makefile文件就是指定编译用到的各个文件。

       sdram.ld文件中,主要的代码是

MEMORY
{
    isram (W!RX) : ORIGIN = 0x402F0400, LENGTH = 63K
    ocmc0 (W!RX) : ORIGIN = 0x40300000, LENGTH = 64K -16K
    ddr   (W!RX) : ORIGIN = 0x8a000000, LENGTH = 512M - 160M
}

这个地址的指定和上面的_start函数的地址对应上就能理解整个内存分布情况了。说明的是isram和ocmc0是am335x内部自带的内存的地址,移植的时候要注意自己采用的mcu是否有这块地址,或者对应的地址是多少。

大体的框架分析差不多了,下面就是得动手移植了。

静待佳音,我移植成功了再分享一下具体的移植过程及移植代码。

有兴趣的小伙伴可以联系我 qq:530655014

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值