|
作者:研一http://www.gzweiyan.com/html/embedded/20080427/30.html
1) 下载源代码
下载最新的uCOS-II-V286版和Michael Anburaj基于S3C2410的1.6.1移植版。根据代码用途的,建立app,s3c2440,ucosii三个目录,分别放置应用程序,平台移植文件和uCOS的源代码。如图:
2) 新建ADS工程
加入所有代码,修改ARM Assembler和C Compiler的编译器类型为ARM920T。为方便调试,编译完的二进制文件由U-BOOT下载到0x31000000的内存地址,所以修改链接参数的代码地址RO Base为0x31000000。如图:
3) 修改时钟频率和总线速率
这一部主要是修改CLKDIVN时钟分频比和MPLL总线速率,可在init.S的初始化汇编环境中设置,
ldr r0,=CLKDIVN ; Set ratios 1:3:6 for FCLK:HCLK:PCLK
ldr r1,=(7)
str r1,[r0]
[ PLL_ON_START
; Configure MPLL
ldr r0,=MPLLCON
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ; Fin=12MHz,Fout=50MHz
str r1,[r0]
]
也可在C的入口函数C_vMain中设置
__vChangeClockDivider(3,1); // 1:3:6 /* already set at init.S */
__vChangeMPllValue(184,2,2); // FCLK=406M
4) 修改内核心跳
Michael Anburaj的移植是使用看门狗作内核心跳,但在S3C2440中,看门狗与AC97控制器共用一个中断,所以需要修改中断跳转和清中断等操作。考虑到看门狗在嵌入式的重要性,这里改用没有输出功能的时钟4作为内核心跳。修改心跳初始化函数FRMWRK_vStartTicker():
void FRMWRK_vStartTicker(U32 wTicksPerSec)
{
……
OS_ENTER_CRITICAL();
pISR_TIMER4 = (U32)__vTimer4Interrupt;
tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
tcfg1 |= S3C2410_TCFG1_MUX4_DIV2;
tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT;
tcnt = (PCLK / 6) / wTicksPerSec;
……
tcon &= ~(7<<20);
tcon |= S3C2410_TCON_T4RELOAD;
tcon |= S3C2410_TCON_T4MANUALUPD;
rTCON = tcon;
rTCNTB4 = tcnt;
tcon |= S3C2410_TCON_T4START;
tcon &= ~S3C2410_TCON_T4MANUALUPD;
rTCON = tcon;
BIT_CLR(rINTMSK, BIT_TIMER4);
OS_EXIT_CRITICAL();
}
5) 修改U-BOOT的中断跳转
利用U-BOOT已有的丰富功能,如烧写,网络,脚本等,可在没有仿真器的情况下大大减少调试的时间。
如果直接下载ucos,一挑战到0x31000000的内存地址,会出现如下的中断信息:
interrupt request
pc : [<3100ab28>] lr : [<e7fffff7>]
sp : 7fbfdfb7 ip : ffffdd7e fp : 33d78a49
r10: 33d78931 r9 : 51000000 r8 : 80000013
r7 : 00000200 r6 : 00000000 r5 : 00500000 r4 : 0000dc7e
r3 : fefefeff r2 : 00000000 r1 : ffffbfff r0 : 80000013
Flags: Nzcv IRQs on FIQs on Mode SVC_32
Resetting CPU ...
原因是U-BOOT的初始化代码接管了中断管理,看U-BOOT的反汇编:
.globl _start
_start: b start_code
33f80000: ea000014 b 33f80058 <start_code>
ldr pc, _undefined_instruction
33f80004: e59ff014 ldr pc, [pc, #20] ; 33f80020 <_undefined_instruction>
ldr pc, _software_interrupt
33f80008: e59ff014 ldr pc, [pc, #20] ; 33f80024 <_software_interrupt>
…….
ldr pc, _irq
33f80018: e59ff014 ldr pc, [pc, #20] ; 33f80034 <_irq>
…….
33f80020 <_undefined_instruction>:
33f80020: 33f80240 mvnccs r0, #4 ; 0x4
33f80024 <_software_interrupt>:
33f80024: 33f802a0 mvnccs r0, #10 ; 0xa
…….
33f80034 <_irq>:
33f80034: 33f80420 mvnccs r0, #536870912 ; 0x20000000
IRQ的中断入口为偏移0x34的33f80420。OK,在C_vMain入口处加一句:
(*(unsigned *)(0x34)) = (U32)UCOS_IRQHandler;
6) 系统测试
添加一个应用程序ex3.c,建立两个子任务,分别不停的打印0和1。主任务每隔1秒打印系统的使用率。运行情况如下:
UCOS_FRAMEWORK Ver 1.15 for S3C2440 (ARM920T from Samsung) :05/03/05
Built using ADS on Apr 26 2008 <10:31:35>
Endian: LITTLE
Processor operating state: ARM
Task start state: ARM
CONSOL: COM0, 115200bps, 8Bit, NP
CPU Clk: 406MHz MMU: ON Cache: ON Write Buf: ON
FLASH_SADDR:00000000h SRAM_SADDR:40000000h SRAM_EADDR:40000fffh
SDRAM_SADDR:30000000h SFR_BADDR :48000000h ISR_BADDR :33ffff00h
Free RAM: 3100edd8h ~ 33ffa7ffh
Developed by Michael Anburaj, http://geocities.com/michaelanburaj/
Ported by WEIYAN TECHNOLOGY, http://www.gzweiyan.com/
Ver 0.1 08/04/26
timer tcon=00500000, tcnt dc7e, tcfg 00000200,00000000
uC/OS-II, The Real-Time Kernel ARM Ported version
Jean J. Labrosse/ (Ported by) Michael Anburaj
WEIYAN TECHNOLOGY http://www.gzweiyan.com
Task1 #1
<-PRESS 'ESC' TO QUIT->
5 0 5 //正在运行的的任务数 当前的cpu使用率 每秒任务切换的次数
01010101010101010101010101010101010101010101010101010101010101010101010101010101 5 1 141
01010101010101010101010101010101010101010101010101010101010101010101010101010101 5 1 141
01010101010101010101010101010101010101010101010101010101010101010101010101010101 5 1 141
01010101010101010101010101010101010101010101010101010101010101010101010101010101 5 1 141
7) 移植小结
这次移植的难点在U-BOOT的中断接管,修改完内核心跳后,内核一运行就自动重启。后来细看输出信息interrupt request才发现这不是ucos输出的,IRQ中断仍由U-BOOT管理。找到问题的原因,解决方法就好办了。可以直接在U-BOOT里通过mw来修改,也可以由ucos来修改。
如果各位朋友在移植过程中遇到什么问题,可联系我们索取该移植包。
伟研科技 专注于Linux系统移植及应用开发
http://www.gzweiyan.com |
|