S3C2440时钟问题uboot乱码

合集下载

mini2440调试进不了中断解决方案

mini2440调试进不了中断解决方案

ldr r0,=SRCPND str r1,[r0] ldr r0,=INTPND str r1,[r0] ldr r0,=INTSUBMSK ldr r1,=0x7fff @all sub interrupt disable, 2002/04/10 str r1,[r0] @@@设置频率 mov r1, #CLK_CTL_BASE ldr r2, clock_locktime str r2, [r1, #oLOCKTIME] mov r1, #CLK_CTL_BASE ldr r2, clkdivn_value str r2, [r1, #oCLKDIVN] mrc p15, 0, r1, c1, c0, 0 @ read ctrl register orr r1, r1, #0xc0000000 @ Asynchronous mcr p15, 0, r1, c1, c0, 0 @ write ctrl register mov r1, #CLK_CTL_BASE ldr r2, mpll_value @ clock default str r2, [r1, #oMPLLCON] @@@@初始化串口 InitUART: @set GPIO for UART mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_H ldr r2, gpio_con_uart str r2, [r1, #oGPIO_CON] ldr r2, gpio_up_uart str r2, [r1, #oGPIO_UP] ldr r1, SerBase mov r2, #0x0 str r2, [r1, #oUFCON] str r2, [r1, #oUMCON] mov r2, #0x3 str r2, [r1, #oULCON] ldr r2, =0x245 str r2, [r1, #oUCON] .equ UART_BRD , ((UART_PCLK / (UART_BAUD_RATE*16)) - 1) mov r2, #UART_BRD str r2, [r1, #oUBRDIV] mov r3, #100 InitUART1:

c语言乱码问题详解

c语言乱码问题详解

c语言乱码问题详解在C语言编程中,乱码问题是一个非常常见的问题。

乱码通常是指在显示或输出字符串时,字符的编码格式不正确,导致字符无法正常显示。

这个问题可能由多种原因引起,本文将对C语言乱码问题进行全面详解。

一、乱码的产生原因1. 编码格式不统一:在C语言编程中,字符串通常使用ASCII编码或UTF-8编码。

如果不同程序或不同文件使用了不同的编码格式,就可能导致乱码。

2. 文件编码不统一:在编写和读取文件时,如果文件本身的编码格式与程序使用的编码格式不统一,也可能导致乱码。

3. 代码页设置不正确:在Windows系统中,代码页设置不正确可能导致乱码。

例如,默认的代码页是936(简体中文),如果设置为其他代码页,就可能导致乱码。

二、乱码的解决方案1. 统一编码格式:在编写程序时,确保所有文件和使用到的库都使用相同的编码格式。

通常建议使用UTF-8编码,因为它可以很好地表示各种字符集,包括简体中文、繁体中文和英文等。

2. 使用正确的代码页:在Windows系统中,确保代码页设置正确。

可以通过修改系统设置或编程时使用`SetConsoleOutputCP()`函数来设置代码页。

3. 使用字符串处理库:对于复杂字符集的支持,可以使用第三方字符串处理库,如iconv或ICU。

这些库可以提供丰富的字符编码转换功能,帮助解决乱码问题。

4. 使用命令行参数:在编写程序时,可以使用命令行参数来指定输入和输出文件的编码格式。

这样,即使在不同环境中运行程序,也可以确保编码的一致性。

三、案例分析下面我们通过一个简单的案例来说明如何解决C语言中的乱码问题。

假设我们有一个简单的C语言程序,用于将一个文本文件的内容读取到一个字符串数组中,然后输出到另一个文本文件。

在编写这个程序时,我们需要注意以下问题:1. 统一编码格式:确保源文件和使用到的库都使用UTF-8编码。

2. 使用正确的代码页:在Windows系统中,确保代码页设置为UTF-8(1200)。

Mini2440 Uboot移植

Mini2440 Uboot移植

第一部分根据uboot-2008.10,移植出能在mini2440 nor flash上运行的uboot1 修改Makefile:在uboot-2008.10顶层目录中的Makefile中,参考smdk2410_config,添加新的配置选项。

# add,flyrizmini2440_config : unconfig@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 NULL s3c24x02 修改cpu/arm920t/start.S:2.1添加支持S3C2440的编译条件/* #if defined(CONFIG_S3C2400)||defined(CONFIG_S3C2410) *//*modify,flyriz*/#if defined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440) 2.2添加S3C2440寄存器的定义#else# define pWTCON 0x53000000# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */# define INTSUBMSK 0x4A00001C# define CLKDIVN 0x4C000014 /* clock divisor register */# endif/*add,flyriz,for 2440,register define*/#define CLK_CTL_BASE 0x4C000000#define MDIV_405 0x7f<<12#define PSDIV_405 0x21#define UPLL_MDIV_48 0x38<<12#define UPLL_PSDIV_48 0x22#define MDIV_200 0xa1<<12#define PSDIV_200 0x31/****************************/2.3修改中断禁止代码# if defined(CONFIG_S3C2410)ldr r1, =0x3ffldr r0, =INTSUBMSKstr r1, [r0]# endif/*add,flyriz*/# if defined(CONFIG_S3C2440)ldr r1, =0x7fff /* S3C2440有15个子中断[0...14] */ldr r0, =INTSUBMSKstr r1, [r0]# endif2.4 修改时钟设置/********************* FCLK:HCLK:PCLK = 1:2:4 ** default FCLK is 120 MHz ! *ldr r0, =CLKDIVNmov r1, #3str r1, [r0]#endif * CONFIG_S3C2400 || CONFIG_S3C2410 *********************//*modify,flyriz*/#if defined(CONFIG_S3C2440)/*FCLK:HCLK:PCLK=1:4:8*/ldr r0,=CLKDIVNmov r1,#5str r1,[r0]mrc p15,0,r1,c1,c0,0 /* CP15中的寄存器C1是一个控制寄存器,用于配置MMU中的一些操作 */orr r1,r1,#0xc0000000mcr p15,0,r1,c1,c0,0mov r1,#CLK_CTL_BASE /* 0x4C000000 LOCKTIME:PLL lock time counter */mov r2,#UPLL_MDIV_48add r2,r2,#UPLL_PSDIV_48str r2,[r1,#0x08] /* 0x4C000008 UPLLCON=0x38<<12||0x22,output 48MHz */mov r2,#MDIV_405add r2,r2,#PSDIV_405str r2,[r1,#0x04] /* 0x4C000004 MPLLCON=0x7f<<12||0x21,output 405MHz */ #elseldr r0,=CLKDIVNmov r1,#3str r1,[r0]mrc p15,0,r1,c1,c0,0orr r1,r1,#0xc0000000mcr p15,0,r1,c1,c0,0mov r1,#CLK_CTL_BASEmov r2,#MDIV_200add r2,r2,#PSDIV_200str r2,[r1,#0x04]#endif#endif /*CONFIG_S3C2400||CONFIG_S3C2410||CONFIG_S3C2440*//**********************************************************/3 修改cpu/arm920t/s3c24x0/interrupts.c3.1 在条件编译的宏定义里加入对s3c2440的支持:/* #if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) *//*modify,flyriz*/#if defined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)||defined(CONFIG_TRAB)/* #elif defined(CONFIG_S3C2410) *//*modify,flyriz*/#elif defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)3.2 在get_tbclk函数中,添加对mini2440的支持:#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)tbclk = timer_load_val * 100;#elif defined(CONFIG_SBC2410X) || \defined(CONFIG_SMDK2410) || \defined(CONFIG_MINI2440) || \defined(CONFIG_VCMA9) /*modify,flyriz,add:CONFIG_MINI2440*/tbclk = CFG_HZ; /*get_tbclk函数的作用?CFG_HZ又是什么?*/4 修改cpu/arm920t/s3c24x0/speed.c4.1 在条件编译的宏定义里加入对s3c2440的支持:/*#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410)|| defined (CONFIG_TRAB)*//*modify,flyriz*/#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_S3C2440) || defined (CONFIG_TRAB) /*#elif defined(CONFIG_S3C2410)*//*modify,flyriz*/#elif defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)4.2 修改get_PLLCLK函数:m = ((r & 0xFF000) >> 12) + 8;p = ((r & 0x003F0) >> 4) + 2;s = r & 0x3;/*add,flyriz*/#if defined(CONFIG_S3C2440)if(pllreg==MPLL)return ((CONFIG_SYS_CLK_FREQ*m*2)/(p<<s)); /*S3C2440中,UPLL与MPLL的计算公式不同*/ else if(pllreg==UPLL)#endif4.3 修改get_HCLK函数:ulong get_HCLK(void){S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();/*return ((clk_power->CLKDIVN&0x2)?get_FCLK()/2:get_FCLK()); delete,flyriz*//*add,flyriz*/#if defined(CONFIG_S3C2440)if(clk_power->CLKDIVN & 0x6){if((clk_power->CLKDIVN & 0x6)==2)return (get_FCLK()/2);if((clk_power->CLKDIVN & 0x6)==6)return ((clk_power->CAMDIVN&0x100)?get_FCLK()/6:get_FCLK()/3);if((clk_power->CLKDIVN & 0x6)==4)return ((clk_power->CAMDIVN&0x200)?get_FCLK()/8:get_FCLK()/4);return (get_FCLK());}else return (get_FCLK());#elsereturn ((clk_power->CLKDIVN&0x2)?get_FCLK()/2:get_FCLK());#endif}5 修改include/asm-arm/mach-types.h,添加mini2440的机器ID(必须与内核提供的ID保持一致):#define MACH_TYPE_GENEVA 1873#define MACH_TYPE_MINI2440 1999 /*add,flyriz,mini2440机器ID,必须与内核提供的ID相同*/6 修改cpu/arm920t/s3c24x0/serial.c/*#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB)*//*modify,flyriz*/#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_S3C2440) || defined (CONFIG_TRAB) /*#elif defined(CONFIG_S3C2410)*//*modify,flyriz*/#elif defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440)7 修改drivers/rtc/s3c24x0_rtc.c/* #elif defined(CONFIG_S3C2410) */#elif defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440) /*modify,flyriz*/8 修改include/s3c24x0.h/*#ifdef CONFIG_S3C2410*/#if defined(CONFIG_S3C2410)||defined(CONFIG_S3C2440) /*modify,flyriz*/(所有ifdef CONFIG_S3C2410全部替换)/* CLOCK & POWER MANAGEMENT (see S3C2400 manual chapter 6) *//* (see S3C2410 manual chapter 7) */typedef struct {S3C24X0_REG32 LOCKTIME;S3C24X0_REG32 MPLLCON;S3C24X0_REG32 UPLLCON;S3C24X0_REG32 CLKCON;S3C24X0_REG32 CLKSLOW;S3C24X0_REG32 CLKDIVN;/*add,flyriz*/#if defined(CONFIG_S3C2440)S3C24X0_REG32 CAMDIVN; /*增加CAMDIVN的定义*/#endif} /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;9 为开发板新建一个目录在board目录中新建一个目录mini2440,将board/smdk2410下的所有文件拷贝到board/mini2440中,然后对mini2440中的文件做修改:将smdk2410.c改为mini2440.c;将Makefile中的代码COBJS :=smdk2410.o flash.o 改为COBJS :=mini2440.o flash.o10 修改board/mini2440/mini2440.c10.1 修改PLL的配置/*****************#elif FCLK_SPEED==1 // Fout = 202.8MHz#define M_MDIV 0xA1#define M_PDIV 0x3#define M_SDIV 0x1#endif#define USB_CLOCK 1*//*modify,flyriz*/#elif FCLK_SPEED==1#if defined(CONFIG_S3C2410)/*Fout=202.8MHz*/#define M_MDIV 0xA1#define M_PDIV 0x3#define M_SDIV 0x1#endif#if defined(CONFIG_S3C2440)/*Fout=405MHz*/#define M_MDIV 0x7f#define M_PDIV 0x2#define M_SDIV 0x1#endif#endif#define USB_CLOCK 1/*****************/10.2 修改UPLL的配置/***************#if USB_CLOCK==0#define U_M_MDIV 0xA1#define U_M_PDIV 0x3#define U_M_SDIV 0x1#elif USB_CLOCK==1#define U_M_MDIV 0x48#define U_M_PDIV 0x3#define U_M_SDIV 0x2#endif*//*modify,flyriz*/#if USB_CLOCK==0#define U_M_MDIV 0xA1#define U_M_PDIV 0x3#define U_M_SDIV 0x1#elif USB_CLOCK==1#if defined(CONFIG_S3C2410) #define U_M_MDIV 0x48#define U_M_PDIV 0x3#endif#if defined(CONFIG_S3C2440) #define U_M_MDIV 0x38#define U_M_PDIV 0x2#endif#define U_M_SDIV 0x2#endif/*****************/10.3 修改board_init函数,以引导内核/* arch number of SMDK2410-Board *//* gd->bd->bi_arch_number = MACH_TYPE_SMDK2410; *//*modify,flyriz*/gd->bd->bi_arch_number = MACH_TYPE_MINI2440;11 修改board/mini2440/lowlevel_init.S中REFRESH的刷新周期/* REFRESH parameter */#define REFEN 0x1 /* Refresh enable */#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh *//* #define Trp 0x0 2clk *//*modify,flyriz*/#define Trp 0x2 /* 4clk */#define Trc 0x3 /* 7clk */#define Tchr 0x2 /* 3clk *//* #define REFCNT 1113 period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) *//*modify,flyriz*/#define REFCNT 1012/**************************************/12 添加并修改配置文件为开发板添加新的配置文件,复制include/configs/smdk2410.h,另存为include/configs/mini2440.h,并对其进行修改12.1 添加s3c2440的宏定义#define CONFIG_ARM920T 1 /* This is an ARM920T Core *//* #define CONFIG_S3C2410 1 in a SAMSUNG S3C2410 SoC *//* #define CONFIG_SMDK2410 1 on a SAMSUNG SMDK2410 Board *//*modify,flyriz*/#define CONFIG_S3C2440 1#define CONFIG_MINI2440 112.2 修改命令提示符#defineCFG_LONGHELP /* undef to save memory *//* #define CFG_PROMPT "SMDK2410 # " Monitor Command Prompt *//*modify,flyriz*/#define CFG_PROMPT "Mini2440 # "一个具备基本功能的UBOOT代码修改部分已经完成。

uboot启动常见的错误汇总

uboot启动常见的错误汇总

【uboot启动常见的错误汇总】1. operating at 100M full duplex mode*** ERROR: `ethaddr' not setdm9000 i/o: 0x5000000, id: 0x90000a46DM9000: running in 16 bit modeMAC: 00:00:00:00:00:00operating at 100M full duplex modeWrong Image Format for bootm commandERROR: can't get kernel image!原因是:没有设置mac地址,需要重新设置setenv ethaddr 01:02:03:04:05:06saveenv/save2.在开发板上ping ubuntu的ip地址ping不通1.网线没插2.ubuntu没有打开3.ping 的过程中,ubuntu会扫描ip地址,会一直去获取ip地址,但是开发板没有分配ip地址的权利,也就是ubuntu获取不了ip地址,同时查看ubuntu 的ip地址是没有的。

1.设置临时的ip地址sudo ifconfig eth0 192.168.1.*2.永久生效在ubuntu的右上角添加静态ip地址。

3.发现ubuntu的右上角网络图标类似于wifi的图标,如何将这个图标改成网络的图标sudo /etc//init.d/network-manager restart如何执行之后,还是wifi图标sudo vi /etc/NetworkManager/NetworkManager.confmanaged=false false --->truesudo /etc//init.d/network-manager restart如果执行之后,还是wifi图标重启系统4.你的pc电脑已经打开wifi网,需要将无线网关闭5.虚拟机网卡设置出错,需要将nat设置为桥接6.换开发板4.ping ubuntu是可以ping通,但是当启动内核的时候出现T TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTubuntu的tftp服务没有开启,重启tftp服务sudo /etc/init.d/tftpd-hpa restartTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTubuntu的ip没了,需要再次设置ip地址sudo ifconfig eth0 192.168.1.*5.uboot启动内核是提示文件没找到,需要将内核和设备树拷贝到tftp服务器的目录6.nfs在启动nfs服务器时,exportfs: /etc/exports [2]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/rootfs".Assuming default behaviour ('no_subtree_check').NOTE: this default has changed since nfs-utils version 1.0.x解决方法:/rootfs *(rw,sync,no_root_squash,no_subtree_check)7.vfs:为应用程序提供统一的接口程序--》fopen ---->open---->vfs---->内核函数---》硬件7.] VFS: Mounted root (nfs filesystem) on device 0:10.[ 2.130000] devtmpfs: error mounting -2[ 2.135000] Freeing unused kernel memory: 232K (c0655000 - c068f000)[ 2.140000] hub 1-3:1.0: USB hub found[ 2.145000] hub 1-3:1.0: 3 ports detected[ 2.150000] Failed to execute /linuxrc (error -2). Attempting defaults...[ 2.160000] Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.解决方法:需要将文件系统拷贝到这个目录。

keil下的s3c2440启动代码分析

keil下的s3c2440启动代码分析

由于片面问题,所以可能会看起来不太美观,可以看附件中的内容。

ARM启动代码相当于我们电脑的BIOS,也就是ARM启动时对处理器的一些初始化及嵌入式系统硬件的一些初始化。

由于它直接面对处理器内核和硬件控制器进行编程,一般都是用汇编语言。

一般包括:中断向量表,初始化存储器系统,初始化堆栈,初始化有特殊要求的断口,设备初始化,变量初始化等。

这几天对着RealView MDK-ARM中自带的启动代码研究了一下,遇到问题又对着数据手册和指令表看了一下,总算对S3C2440A的硬件有了一个大致的了解。

学习嵌入式系统重在系统,学习ARM只是为学习嵌入式系统铺路,懒猫比较笨可能在上系统之前要裸奔几天以强化以下对S3C2440A内部结构的了解。

把MDK自带的S3C2440A.S文件的注释发一下,这些是懒猫结合数据手册与ARM指令表理解了,可能会有错误,放在这里只是引导一下像我一样还没有入门的兄弟们,希望你们不要害怕ARM害怕嵌入式,老毛他老人家说的对,世上无难事,只怕有心人,ARM指令就那么多,看一遍不会就多看几遍,还有一定要学习看软件自带的帮助文件.;/*****************************************************************************/;/* S3C2440.S: Startup file for Samsung S3C440 */;/*****************************************************************************/;/* <<< Use Configuration Wizard in Context Menu >>> */ ;/*****************************************************************************/;/* This file is part of the uVision/ARM development tools. */ ;/* Copyright (c) 2005-2008 Keil Software. All rights reserved. */ ;/* This software may only be used under the terms of a valid, current, */;/* end user licence from KEIL for a compatible version of KEIL softwar e */;/* development tools. Nothing else gives you the right to use this softwa re. */;/*****************************************************************************/;下面这些参数是与CPSR状态寄存器有关;参数的由来:这里各个模式的参数是由寄存器CPSR的模式位设置M[4:0]得来的,;比如这里的用户模式,CPSR的M[4:0]设置为10000就是0x10。

如何解决乱码问题总结

如何解决乱码问题总结
<url-pattern>/*<url-pattern>
</filter-mapping>
3.URL中的中文问题
对于直接通过在URL中传递中文参数,如“http://localhost/a.jsp?str=中文”这样的get请求,在服务端用request.getParameter("name")时返回的往往是乱码。按以上的做法设置Filter没有用,用request.setCharacterEncoding("gbk")的方式,仍然不管用。
httpServletResponse.setContentType("text/html;charset=gbk")),最好同时在JSP页面的head部分加上<meta http-equiv="Content-Type" content="text/html;charset=gbk">
·在每次要输出中文的地方主动转换编码方式,比如要在页面中输入“中文”二字,就可以用以下方式:
<%
String str="中文";
byte[] tmpbyte=str.getBtyes("ISO-8859-1");
str=new String(tmpbyte);
out.print(str);
%>
2.获取表单提交的数据时的中文乱码问题
%>
<html>
<head>
<title>中文Test</title>
<meta http-equiv="Content-Type" content="text/html;charset=gbk">

串口通信乱码详细处理方法

串口通信乱码详细处理方法

串口通信乱码详细处理方法
串口通信乱码是串口通信中常见的问题之一,其中最常见的问题就是由于使用不当导致了数据的丢失或者传输的数据出现了乱码。

本文将会详细介绍关于串口通信乱码的一些处理方法。

1. 波特率设置
波特率是串口通信的基础配置之一,必须保证发送端和接收端的波特率一致,否则就会导致收发数据出现错误。

如果需要在串口传输中稳定传输数据,我们需要适当降低波特率。

一般情况下,如果数据传输远距离或者串口数据传输速度较快,建议使用较低的波特率。

2. 校验位和数据位的设置
在串口通信中,校验位和数据位也是非常重要的参数之一,校验位用于检验数据是否出现了传输错误,通过设置一个校验位,我们可以有效地减少数据出现乱码的情况。

同时,数据位的设置也会对传输的数据进行影响,如果数据位设置不当,也会导致发送和接收的数据出现乱码。

3. 帧头和帧尾设置
帧头和帧尾是串口通信中的重要标志,可以用于标记传输数据的起始和结束,防止出现串口传输数据丢失等情况。

在接收数据时,可以通过判断帧头和帧尾是否正常来判断数据是否正确。

4. 缓冲区大小设置
缓冲区大小也是影响串口通信乱码情况的一个重要因素,如果缓冲区设置的过小,就会导致数据的缓存不够,从而出现数据丢失或传输乱码的情况。

因此,在确保串口通信稳定的前提下,我们需要适当增大缓冲区的大小。

串口通信乱码是一个常见的问题,但只要我们对串口通信的相关参数进行适当设置,并合理使用各种处理方式,就可以有效地减少数据丢失和传输乱码的情况。

在使用串口通信进行数据传输时,需要根据实际情况设置相关参数,保证传输数据的成功。

2440启动串口输出乱码问题

2440启动串口输出乱码问题

2440 移植2.6.30 (转)解压缩内核压缩文件后进入到目录中,然后修改Makefile,找到ARCH ?=CROSS_COMPILE ?=这两项,不修改这两项的话将会默认使用x86的配置,这里修改为ARCH ?= armCROSS_COMPILE ?= arm-linux-arm-linux- 是交叉编译器~ 这里我使用的交叉编译器为友善送的arm-linux-gcc-4.3.2.tgz,带EABI然后执行make menuconfig,然后进入System Type中看看是否为ARM体系~第一行为ARM system type 说明没错~ 然后在ARM system type中选择SamSung“S3C2410...”随后在下面出现的S3C2440 Machines中选择SMDK2440退出保存~ 执行make zImage出现ERRORdrivers/video/console/vgacon.c:510:error “PCIMEM_BASE undeclared”是在vgacon_startup中,vgacon是啥?~ 不认识~ 应该是不必要的东西~ 去掉它~vim drivers/video/console/Makefile在里面看见了这句obj-$(CONFIG_VGA_CONSOLE) += vgacon.o然后执行find ./ -name “Kconfig” | xargs grep “VGA_CONSOLE”看见config VGA_CONSOLE 在driver/video/console/Kconfig中也就是说在驱动->视频->终端中,执行make menuconfig在Device Drivers->Graphics Support->Console display driver support中发现了VGA text console去掉它,保存设置后再编译编译完成后将在arch/arm/boot中得到zImage文件使用SuperVivi的USB加载功能启动这个内核文件~ 得到下列输出zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux........................................................................................................ done, booting the kernel.失败信息不够丰富~ 根据kasim大大的指点,在配置中进入Kernel hacking打开Kernel debugging和Kernel low-level debugging functions 还有Kernel low-level debugging messages via S3C UART保存后再编译运行zImage后得下列输出zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux........................................................................................................ done, booting the kernel.Error: unrecognized/unsupported machine ID (r1 = 0x000007cf).Available machine support:ID (hex) NAME0000016a SMDK2440Please check your kernel config and/or bootloader.失败原来是machine的ID和Supervivi传递进来的ID不匹配~关于machine ID,可以参考一下这篇文章<2.6.18-2内核中对S3C2440的引导启动分析>虽然版本老了点,但是核心思想还是没有变vim arch/arm/mach-s3c2440/mach-smdk2440.c在最后一段有这句MACHINE_START(S3C2440 , ”SMDK2440”)这里S3C2440就是machine ID的代号~ 呢具体值是多少呢?~在arch/arm/tools/mach-types中s3c2440 ARCH_S3C2440 S3C2440 362原来我们的machine ID是362~呢bootloader传递进来的值是多少呢?~Error: unrecognized/unsupported machine ID (r1 = 0x000007cf).注意到没有?~ 0x7CF转换成10进制也就是1999修改mach-types中的对应项s3c2440 ARCH_S3C2440 S3C2440 1999虽然这样就和下面MINI2440的1999冲突了,但是只要不加入MINI2440的配置就没事修改后编译,再执行zImage后得下列输出zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux........................................................................................................ done, booting the kernel.失败咦?~ 啥都没有?~ 最起码也应该有个乱码吧这时候我的第一反应是会不会没有跳入到start_kernel中所以马上编辑init/main.c,在start_kernel的前部加上printk(KERN_INFO “in start_kernel \n”);但是这个时候内核还没有初始化,所以printk是没有作用的~继续得到kasim大大的指点,编辑kernel/printk.c中的printk函数{va_list args;int r;#ifdef CONFIG_DEBUG_LLextern void printascii(const char *);char buff[256];#endifva_start(args, fmt);r = vprintk(fmt, args);#ifdef CONFIG_DEBUG_LLvsprintf(buff, fmt, args);#endifva_end(args);#ifdef CONFIG_DEBUG_LLprintascii(buff);#endifreturn r;}编译后执行zImage,得下列输出zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux........................................................................................................ done, booting the kernel.<6>in start_kernel<6>Initializing cgroup subsys cpuset<6>Initializing cgroup subsys cpu<5>Linux version 2.6.30.3 (wolf@ubuntu) (gcc version 4.3.2 (Sourcery G++ Lite2008q3-72) ) #4 Wed Aug 5 16:54:49 CST 2009 ..................................................失败虽然正常输出了~ 有进入start_kernel~ 但是为什么之前每输出呢?~ 会不会是没有找到输出设备在输出中看到这行<5>Kernel command line: noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0 console=ttySAC0 会不会是没有ttySAC0这个设备呢~ 在内核中搜索ttySAC 在driver/serial/samsung.c中得到对应项目这时候我猜想会不会没有加载samsung.c , 经过一轮Makefile和Kconfig的查询, 发现对应选项在Device Drivers->Character devices->Serial drivers中一看,原来根本就没有加载Samsung SoC serial support , 选成静态编译之后又出现了Support for console on Samsung SoC serial port ,就是它了,选上, 退出的时候顺便把Kernel low-level debugging functions给取消了否则我们设置的printk会自行输出,就不知道ttySAC有没有加载成功了编译后执行,得下列输出zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux......................................................................................................... done, booting the kernel.w# DpñGpGp´ó70ÇC¼ØûÛ»›3ó•ó¸Û0ƒw#DpñGpGp´ó•tØ›•p¸›7¿³ó•\@û7¼¿[£¼Û3•¼ó;£¸ÀÛ;[7û;D°•D@GoGpGpíó•t›7•{ð#ßóÄ;›•770ÄÄ3Çß;GoDh}û7wœ´{…[ó7ûÛ›30°ôܸ‡#_sÄ;›•770Øijœ¼DG@ÁôÛ•ûÄ;•sÄ›£Ø›•DŽ³ÃÛ70ÄGpÁ4ßœ»ôGã›30³D˜ßF[s˜£ÀÛû70ÛD8ßÄ4G8ôGv£°ÇÃGpÍ´0ƒ†# DpñGš´;óC…[4¸F¸ÄÛtÜàGp}4GGÇ4tD@Ä38ÀGpGß ôØ Û›ŸÄÛD\Cûƒ£¸ƒ;7v›Ã30Ü›4Û´£ô¼;C3[;7ù³û770‡¸°[•4tD@Ä38ÀGpGß ´´p‡ƒ•ô¼Û7ŸtÛG»4œØ…Çpíƒw# .......................................失败但这说明ttySAC加载成功了~ 不过为什么是乱码呢?~这时候就需要对比友善的配置和我们的配置有什么不同了~打开友善送的linux-2.6.29,观察arch/arm/mach-s3c2440/mach-mini2440.c和我们的2.6.30.4下面的arch/arm/mach-s3c2440/mach-smdk2440.c有什么不同由于乱码主要是时钟问题,所以我们重点观察UART的设置和基本设置,其它什么NAND LCD 的就不看先修改smdk2440_uartcfgs[][2] = {.ulcon = 0x03,}修改s3c24xx_init_clocks(12000000);然后编译再运行,输出为zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux......................................................................................................... done, booting the kernel.[ 0.000000] in start_kernel[ 0.000000] Initializing cgroup subsys cpuset[ 0.000000] Initializing cgroup subsys cpu ...........................最后为Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)失败终于可以正常输出了,但是根文件系统挂载失败因为板子上的根文件系统为yaffs2 这时候内核还没有这个文件系统的支持,需要我们加上去拷贝友善的送的2.6.29下的fs/yaffs2目录到我们的fs目录下然后修改观察一下友善的送的2.6.29下的fs/Kconfig 和fs/Makefile和我们的有什么不同在我们的Kconfig中的source “fs/jffs2/Kconfig” 上面加上source “fs/yaffs2/Kconfig”在Makefile中的obj-$(CONFIG_FAT_FS) += fat/ 上面加上obj-$(CONFIG_YAFFS_FS) += yaffs2/然后在配置的File systems->Miscellaneous filesystems 中选上“YAFFS2 file system support” “Autoselect yaffs2 format” “Cache short names in RAM”然后编译运行,输出如下......................Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)失败还是不行,往上看几行VFS: Cannot open root device "mtdblock2" or unknown-block(0,0)Please append a correct "root=" boot option; here are the available partitions:Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)原来是没有可用的分区这个时候就要更正我们的NAND配置了还是对照友善送的linux-2.6.29,观察arch/arm/plat-s3c24xx/common-friendly-smdk.c来修改我们的arch/arm/plat-s3c24xx/common-smdk.c主要修改smdk_default_nand_part[]{[0] = {.name = “supervivi”,.size = 0x00060000,.offset = 0,},[1] = {.name = “Kernel”,.offset = 0x00060000,.size = 0x00200000,},[2] = {.name = “root”,.offset = 0x00260000,.size = 1024*1024*1024,},[3] = {.name = “nand”,.offset = 0x00000000,.size = 1024*1024*1024,}};编译后运行,输出VFS: Cannot open root device "mtdblock2" or unknown-block(0,0)Please append a correct "root=" boot option; here are the available partitions:Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)失败还是不行,连最起码的分区都没有看见,会不会是MTD没有加载呢?~打开配置进入Device DriversMemory Technology Device ......... 前面是个M~ 说明这个模块是动态加载的,而我们编译的zImage里面只有静态模块将MTD选为静态加载,然后进入MTD配置中看看还有什么需要选的NAND Device Support 这个也是动态,选为静态加载进入NAND Device Support原来连NAND Flash support for S3C2410/S3C2440 SoC都没选,马上选为静态加载保存配置后编译运行,再运行输出如下:NAND device: Manufacturer ID: 0xec, Chip ID: 0xf1 (Samsung NAND 128MiB 3,3V 8-bit) Scanning device for bad blocksCreating 4 MTD partitions on "NAND 128MiB 3,3V 8-bit":0x000000000000-0x000000060000 : "supervivi"0x000000060000-0x000000260000 : "Kernel"0x000000260000-0x000040260000 : "root"mtd: partition "root" extends beyond the end of device "NAND 128MiB 3,3V 8-bit" -- size truncated to 0x7da00000x000000000000-0x000040000000 : "nand"mtd: partition "nand" extends beyond the end of device "NAND 128MiB 3,3V 8-bit" -- size truncated to 0x8000000 ...............................VFS: Cannot open root device "mtdblock2" or unknown-block(0,0)Please append a correct "root=" boot option; here are the available partitions:Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)失败还是没有可用分区,虽然成功分辨了分区,但是没有加载成功,估计还是在MTD的模块选择上这时候需要对照友善的配置,经过对比,发现在友善的配置中静态编译了MTD中的下面3个模块Direct char device access to MTD devicesCommon interface to block layer for MTD …translation layers‟Caching block device access to MTD devices我们也选为静态编译保存配置后编译运行,输出如下List of all partitions:1f00 384 mtdblock0 (driver?)1f01 2048 mtdblock1 (driver?)1f02 128640 mtdblock2 (driver?)1f03 131072 mtdblock3 (driver?)No filesystem could mount root, tried: cramfsKernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)分区加载成功了,但是文件系统却不能识别,我们之前不是已经加入了yaffs2么?~回到配置中再看,原来是动态编译,并没有真正进入到内核之中,选为静态编译~保存配置后编译,输出为yaffs: dev is 32505858 name is "mtdblock2"yaffs: passed flags ""yaffs: Attempting MTD mount on 31.2, "mtdblock2"yaffs: auto selecting yaffs2yaffs_read_super: isCheckpointed 0VFS: Mounted root (yaffs filesystem) on device 31:2.Freeing init memory: 128KKernel panic - not syncing: Attempted to kill init!失败依然错误,这个时候懵了,哪里错呢~ 没办法,只能对照着友善的配置一个个大模块对着来改当改到Kernel Features的时候错误消失了,原来需要选上Use the ARM EABI to compile the kernelAllow old ABI binaries to run with thie Kernel为什么呢?~ Google了一下,原来友善的根文件系统在编译的时候也启用了EABI特性,内核和文件系统需要对上文件系统用了EABI 内核也要用EABI 内核不用EABI 也只能读取不用EABI的文件系统选上这两项之后再编译,运行,输出如下yaffs: dev is 32505858 name is "mtdblock2"yaffs: passed flags ""yaffs: Attempting MTD mount on 31.2, "mtdblock2"yaffs: auto selecting yaffs2yaffs_read_super: isCheckpointed 0VFS: Mounted root (yaffs filesystem) on device 31:2.Freeing init memory: 128Kmount: mounting none on /proc/bus/usb failed: No such file or directoryhwclock: can't open '/dev/misc/rtc': No such file or directory[01/Jan/1970:00:00:13 +0000] boa: server version Boa/0.94.13[01/Jan/1970:00:00:13 +0000] boa: server built Mar 26 2009 at 15:28:42.[01/Jan/1970:00:00:13 +0000] boa: starting server pid=845, port 80open device leds: No such file or directoryTry to bring eth0 interface up......ifconfig: SIOCGIFFLAGS: No such deviceifconfig: SIOCSIFHWADDR: No such deviceifconfig: SIOCSIFADDR: No such deviceroute: SIOCADDRT: No such processDoneifconfig: SIOCSIFADDR: No such devicePlease press Enter to activate this console.[root@FriendlyARM /]#成功了,ls后输出如下bin home lost+found proc sys vardev lib mini2440 root tmp wwwetc linuxrc opt sbin usr不过ifconfig命令没有成功,继续来配置网卡对比友善的mach-mini2440.c文件,发现我们的mach-smdk2440.c中的smdk2440_devices[]数组并没有&s3c_device_dm9k这个结构,加上,追踪发现该数据结构在arch/arm/plat-s3c24xx/devs.c中,我们的devs.c中没有该数据结构的定义,加上#include <linux/dm9000.h>static struct resource s3c_dm9k_resource[] = {[0] = {.start = S3C2410_CS4,.end = S3C2410_CS4 + 3,.flags = IORESOURCE_MEM,},[1] = {.start = S3C2410_CS4 + 4,.end = S3C2410_CS4 + 4 + 3,.flags = IORESOURCE_MEM,},[2] = {.start = IRQ_EINT7,.end = IRQ_EINT7,.flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,},};static struct dm9000_plat_data s3c_dm9k_platdata = {.flags = DM9000_PLATF_16BITONLY,};struct platform_device s3c_device_dm9k = {.name = “dm9000”,.id = 0;.num_resources = ARRAY_SIZE(s3c_dm9k_resource),.resource = s3c_dm9k_resource,.dev = {.platform_data = &s3c_dm9k_platdata,}};EXPORT_SYMBOL(s3c_device_dm9k);编译,出错,error : s3c_device_dm9k undeclared here找不到结构?~ 打开mach-smdk2440.c看看有什么头文件比较显眼的就是<plat/s3c2410.h><plat/s3c2440.h><plat/devs.h>,我们刚才编辑的文件是devs.c呢么devs.h的可能性较高,通过搜索,这个devs.h在/arch/arm/plat-s3c/include/plat/中,打开,BINGO,里面都是devs.c的数据定义加上我们的s3c_device_dm9kextern struct platform_device s3c_device_dm9k;再编译,通过了,不过这个时候先别急,我们只添加了设备,驱动有没有静态加载呢?~ 打开配置Device Drivers->Networks device support->Ethernet(10 or 100Mbit)DM9000 support没选上,马上选为静态编译保存配置,编译后运行,输出如下Try to bring eth0 interface up......说明DM9000配置成功使用ping命令进行测试,发现丢包率高达78%是不是驱动没设置好呢?~ 比较了一下友善的driver/net/dm9000.c和2.6.30.4的dm9000.c,发现明显不同直接拷贝友善的dm9000.c和dm9000.h过来编译后运行,顺利进入终端,然后运行PING丢包改善,基本无丢包我对这次内核移植的总结是:一步步来~ 先做好终端输出再挂载好根文件系统最后才考虑其它驱动的配置到此移植就基本结束了= 3=)/ 感谢阅读。

u-boot制作编译过程ok

u-boot制作编译过程ok

2.1.5 UBOOT的制作过程1.第一步:修改makefile,目的告诉makefile导入的工程名是什么。

1)在/1niuedu/u-boot-1.3.4的Makefile的2494行进行COPY后进行修改,范例如下:将smdk2410_config : unconfig@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0 复制并修改为:edu2440_config: unconfig@$(MKCONFIG) $(@:_config=) arm arm920t edu2440 NULL s3c24x02)交叉编译143 144修改为(很多u-boot为默认,一般不修改,如不同需要修改)ifeq ($(ARCH),arm)CROSS_COMPILE = arm-linux-说明:在顶层Makefile(u-boot文件中)中为开发板添加新的配置选项,使用已有的配置项目为例复制修改如下代码:Smdk2410_config:unconfig(2497行)(告诉makefile导入的工程名是怎么设置的) @./mkconfig$(@:_config=)arm arm 920t smdk2410 NULL s3c24x0 Arm:CPU架构Arm920t:CPU类型,对应cpu/arm920t目录xyd2440:开发板型号,对应board/xyd2440NULL:开发者s3c2440:片上系统(SOC)2.第二步:配置开发板选项,修改board中相应开发板选项1)在board目录中将smdk2410复制,然后修改名字为edu2440。

2)在board/edu2440目录下将smdk2410.c修改为edu2440.c(可能运行不了,那么再做如下修改)将E:\信盈达常用资料库\嵌入式配套资料\mini2440-20100717光盘资料\linux\bootloader\u-boot-1.1.6\board\open24x0里面的:boot_init.c,open24x0.c两个文件copy到board-edu2440文件下面。

串口接收数据乱码原因总结

串口接收数据乱码原因总结

串口接收数据乱码原因总结串口接收数据乱码原因总结1. 引言在进行串口通信时,经常会遇到串口接收数据乱码的问题。

解决这个问题需要深入了解导致串口乱码的原因。

本文将总结常见的串口接收数据乱码原因,并提供解决方案。

2. 波特率不匹配问题波特率是串口通信中非常重要的参数,它表示每秒钟传输的位数。

如果发送端和接收端的波特率不一致,会导致接收数据乱码。

解决方法是确保发送端和接收端的波特率设置一致。

3. 数据位、停止位、校验位设置错误串口通信中,数据位、停止位和校验位也是非常重要的参数。

如果设置不正确,会导致接收数据乱码。

解决方法是在发送端和接收端同时设置相同的数据位、停止位和校验位。

4. 电器干扰串口通信受到电器干扰也可能导致数据乱码。

当串口线路与高压电缆或电磁设备靠近时,会引入干扰信号,使接收到的数据产生错误。

解决方法是尽量避免串口线与高压电缆、电磁设备等干扰源靠近,使用屏蔽线或滤波电路也能有效减少干扰。

5. 数据传输过程中的传输错误数据在传输过程中可能会出现错误,例如位错误、帧错误等。

当出现传输错误时,接收到的数据可能会出现乱码。

解决方法是在数据传输过程中使用校验和或CRC等校验方式,来检测和纠正传输错误。

6. 接收端缓冲区溢出当接收端的缓冲区容量无法满足高速数据传输时,会导致缓冲区溢出,进而导致接收数据乱码。

解决方法是增大接收端缓冲区的容量,或者采用流控制技术,控制数据的发送速率,以避免缓冲区溢出。

7. 其他因素除了以上几个常见原因外,还有一些其他因素可能导致串口接收数据乱码,例如硬件故障、软件问题等。

针对这些问题,需要进行更详细的故障排查和调试。

8. 总结串口接收数据乱码是串口通信过程中常见的问题。

解决这个问题需要从波特率、数据位、停止位、校验位等参数设置开始。

电器干扰、传输错误、缓冲区溢出等因素也可能导致乱码。

通过合理设置参数、减少干扰、增大缓冲区容量等方法,可以有效地解决串口接收数据乱码问题。

9. 观点和理解在解决串口接收数据乱码问题时,首先需要对串口通信原理有一定的了解。

uboot分析和笔记

uboot分析和笔记

uboot一、uboot是ppcboot和armboot合并而成,现在主流的bootloader为uboot和redboot二、bootm addr_kernel addr_initrd三、移植uboot时最好(一定)要找到一个自己板子的原形(即自己的板子是在这个板子上做一些修改而来的)的版本,这样就可以事半功倍。

这样要修改的地方就比较少,也比较容易了。

uboot支持很多平台,与一个具体平台相关的主要有三个地方:1、./include/configs/xxxxx.h, 主要定义了flash、sdram的起始地址等信息,一般要修改flash的起始地址、大小,有时候会有位宽等。

2、./board/xxxxx/*,这个目录下主要有两三个.c文件,主要为该平台的初始化和flash操作的函数。

有时候flash的操作需要修改,不过一般都是找一个现有的支持该flash的驱动,一般情况在uboot 别的./board/平台下就会有现成的,拷贝过了就可以了。

3、./cpu/xxxxxx/arch_xxx/xxxxxx/*, 一般是此cpu的初始等函数。

四、具体移植的时候最多涉及到的会是./include/configs/xxxx.h,如果有现成的平台(uboot现在支持绝大部分我们常用的平台),可能只需要对着原来的xxxx.h文件,修改几个我们在硬件上修改了的地方,一般会是flash的起始地址、大小;内存大小(内存的起始地址应该都是0);uboot设置信息保存的地址和长度;console 口和它的波特率;默认的设置;uboot的入口地址等(具体情况可能会有一些变化),如果不是从相同的平台移植,可能会比较麻烦,因为这时候要修改一些和此cpu相关的一些寄存器、频率和内存等硬件方面的东西了(也在这个xxxx.h中),虽然这时改动的地方也不多,但是会很痛苦,因为经常不知道要改哪里或者改为多少。

所以可能需要参考cpu的datasheet和到网上找一些资料了并且慢慢试了。

基于S3C2440的Uboot分析与移植

基于S3C2440的Uboot分析与移植
运 行地 址 改为 .O O 0 ,0 0 = x 0 00 0 。跳线 选择 从 No ls r ah F












UB o ∞81 f g ‘21 -0 t2 0(u I 9 1一明:1“) 2:
¨ I o n Rl ∞ B J w I ’ S f d 日 I 8f l :D  ̄ (
_ _

=0嗍 哪明 =0帅 x 嗍 :0帅
帅帅: I C NI e etd b o r r e .I i s n trc M- e 1 I OE C O s lc e yb ad d b s i o e MI d R N E l d! d
2 6M B s i I : sr a n eil 0t u : sr a eil Er r : sr a eil F 2 ‘ *一 L ‘B
源 代码 。U o t 目录下共有 3 b o根 0个子 目录 ,可 以分为
4类 :
2 2 产 品应用 Pou t pi 2 rdcApl d e
2 1 年 第 2 卷 第 5期 02 1
ht:ww . Sa r. t l we -. gc pl ・ o n
计 算 机 系 统 应 用
墙, 重启 xn t. i d e d服务 ,开放 T 服务 。在/ cep r 邱 e / ot t x s
结 构表 示一 个 Na dFah芯 片 。这个 结 构体 中包 含 n ls
了 关于 Na dFah的地 址信 息 、读 写方 法 、E C模 n ls C
式 、硬 件控 制 等 一 系列 低 层机 制 【,因 此新 驱动 的 5 】 编 写将 变得 更 加 方便 ,只 需修 改 该 结构 体 的相应 成

S3C2440启动流程

S3C2440启动流程

我想请问下。

主板上的DL1灯是在什么阶段点亮的?[2010-6-13 下午02:40:44] michael: 早上打电话给你,还怕打扰你休息了。

原来你们也需要上班。

呵呵[2010-6-13 下午02:40:58] Zhilong Wu: 应该在uboot 里.一开机的时候.[2010-6-13 下午02:42:00] michael: 我们现在有些板启动不了。

发现UART口没有U-BOOT输出信息。

DL1灯不亮[2010-6-13 下午02:44:03] Zhilong Wu: 每个flash 芯片,烧uboot的时候,有没有重新读出一遍,做检查. 确保uboot 是烧好的[2010-6-13 下午02:44:05] michael: DL1灯是UBOOT来控制的还是什么模块控制的?[2010-6-13 下午02:44:51] Zhilong Wu: uboot , 通过cpu的io[2010-6-13 下午02:47:44] michael: 烧写UBOOT的时候,应该是怎样的流程?我们现在是erase--->blank_check-->program---->verify[2010-6-13 下午02:48:07] Zhilong Wu: 这样也可以[2010-6-13 下午02:49:42] michael: DL1有几个阶段:[2010-6-13 下午02:50:12] michael: 不亮,常亮,慢闪,快速[2010-6-13 下午02:50:32] Zhilong Wu: 在uboot 就是一个状态.[2010-6-13 下午02:50:46] Zhilong Wu: 长亮.[2010-6-13 下午02:51:12] Zhilong Wu: 能闪的时候,表示uboot 没问题.起来wince 了[2010-6-13 下午02:51:21] michael: 噢。

UBOOT从NAND FLASH启动分析

UBOOT从NAND FLASH启动分析

UBOOT从NAND FLASH启动分析UBOOT从NAND FLASH启动分析在分析启动代码之前先看一下S3C2440的NAND启动:在配置NAND启动模式之后,S3C2440上电会先将NAND中的0x0 - 0x1000共4096字节的数据拷贝到位于Bank0中的Boot Internal SRAM上Bank0如下图:可以看出Boot Internal SRAM为4KB大小,也正是因为Boot Internal SRAM只有4KB 大小,所以只能从NAND中拷贝4K的内容= 3= 这个Boot Internal SRAM是配置为NAND FLASH启动模式才有的这4K内容是什么呢?~ 这就要看Uboot的镜像文件中是如何进行连接的了~连接脚本在board/smdk2440/u-boot.lds中,如下SECTIONS{. = 0x00000000;. = ALIGN(4);.text :{cpu/arm920t/start.o (.text)cpu/arm920t/s3c24x0/nand_read.o (.text)*(.text)}. = ALIGN(4);.rodata : { *(.rodata) }. = ALIGN(4);.data : { *(.data) }. = ALIGN(4);.got : { *(.got) }. = .;__u_boot_cmd_start = .;.u_boot_cmd : { *(.u_boot_cmd) }__u_boot_cmd_end = .;. = ALIGN(4);__bss_start = .;.bss : { *(.bss) }_end = .;}.text为代码段,可以看出cpu/arm920t/start.o在代码段的最前面,所以会先执行start.o 中的代码连接完成后的镜像文件的前4K如下cpu/arm920t/start.o(.text).text 0x33f80000 0x4e0 cpu/arm920t/start.o0x33f80050 IRQ_STACK_START0x33f80048 _bss_start0x33f8004c _bss_end0x33f80044 _armboot_start0x33f80000 _start0x33f80054 FIQ_STACK_STARTcpu/arm920t/s3c24x0/nand_read.o(.text).text 0x33f804e0 0x1b8 cpu/arm920t/s3c24x0/nand_read.o0x33f804e0 nand_read_ll*(.text).text 0x33f80698 0x64 board/smdk2440/libsmdk2440.a(lowlevel_init.o)0x33f8069c lowlevel_init.text 0x33f806fc 0x280 cpu/arm920t/libarm920t.a(interrupts.o)0x33f80934 do_fiq0x33f80880 do_undefined_instruction0x33f80744 show_regs0x33f80958 do_irq0x33f80728 bad_mode0x33f808c8 do_prefetch_abort0x33f8070c disable_interrupts0x33f80910 do_not_used0x33f808ec do_data_abort0x33f808a4 do_software_interrupt0x33f806fc enable_interrupts.text 0x33f8097c 0x250 cpu/arm920t/s3c24x0/libs3c24x0.a(interrupts.o)0x33f80aa4 set_timer0x33f80a20 reset_timer0x33f8097c interrupt_init0x33f80ba0 get_tbclk0x33f80a90 get_timer0x33f809f0 reset_timer_masked0x33f80a24 get_timer_masked0x33f80ab4 udelay0x33f80b10 udelay_masked0x33f80bac reset_cpu0x33f80b8c get_ticks.text 0x33f80bcc 0x150 cpu/arm920t/s3c24x0/libs3c24x0.a(speed.o)0x33f80c4c get_HCLK0x33f80cec get_PCLK0x33f80c44 get_FCLK0x33f80d14 get_UCLK.text 0x33f80d1c 0x1e8 cpu/arm920t/s3c24x0/libs3c24x0.a(cmd_s3c24xx.o) 0x33f80d8c do_s3c24xx.text 0x33f80f04 0xdc cpu/arm920t/s3c24x0/libs3c24x0.a(serial.o)0x33f80f04 serial_setbrg0x33f80fa8 serial_tstc0x33f80f80 serial_putc0x33f80f58 serial_init0x33f80fb8 serial_puts0x33f80f68 serial_getc.text 0x33f80fe0 0x140 lib_arm/libarm.a(_divsi3.o)0x33f80fe0 __divsi3如何设置从0x33f80000开始呢?~这是链接的时候指定的在根目录下面的config.mk中有下面一句LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)关键就是其中的-Ttext $(TEXT_BASE),这句指明了代码段的起始地址而TEXT_BASE在board/smdk2440/config.mk中定义TEXT_BASE = 0x33F8 0000 为什么是0x33F8 0000呢?~这是将NAND中Uboot拷贝到RAM中的起始地址,所以在代码拷贝到RAM之前不能使用绝对地址来寻址数据,只能用相对地址在以下将用虚拟地址来指Uboot在RAM中的地址,也就是0x33F8 0000现在来看代码cpu/arm920t/start.S_start: ;异常处理向量表b start_codeldr pc, _undefined_instruction ;未定义指令异常:0x00000004ldr pc, _software_interrupt ;软中断异常:0x00000008ldr pc, _prefetch_abort ;预取异常:0x0000000Cldr pc, _data_abort ;数据异常:0x00000010ldr pc, _not_used ;未使用:0x00000014ldr pc, _irq ;外部中断请求IRQ:0x00000018ldr pc, _fiq ;快束中断请求FIQ:0x0000001Cb start_code在虚拟地址0x33F8 0000处, 拷贝到Boot Internal SRAM后则位于0x0处,所以b start_code是第一条执行的指令,start_code在cpu/arm920t/start.S中代码如下://读取CPSR寄存器的内容到R0mrs r0,cpsr//清除R0中的0 - 4 这5个位后保存到R0中//也就是清除用户模式位bic r0,r0,#0x1f//置R0的0 1 4 6 7 位为真//也就是选择SVC模式,同时IRQ和FIQ被禁止,处理器处于ARM状态//关闭中断和快速中断orr r0,r0,#0xd3//将R0中的值保存到CPSR上msr cpsr,r0# define pWTCON 0x53000000 ;看门狗控制寄存器WTCON# define INTMSK 0x4A000008 ;中断屏蔽寄存器INTMSK# define INTSUBMSK 0x4A00001C ;辅助中断屏蔽寄存器,由于外设中断源太多,要用此寄存器屏蔽剩余的中断源# define LOCKTIME 0x4c000000 ;PLL锁定时间计数寄存器# define MPLLCON 0x4c000004 ;主时钟锁相环控制寄存器# define UPLLCON 0x4c000008# define CLKDIVN 0x4C000014 ;时钟分频寄存器/* clock divisor register */# define INTSUBMSK_val 0xffff# define MPLLCON_val ((184 12) + (2 4) + 2) /*406M*/# define UPLLCON_val ((60 12) + (4 4) + 2) /* 47M */# define CLKDIVN_val 7 /* FCLK:HCLK:PCLK = 1:3:6 */# define CAMDIVN 0x4C000018//取得看门狗寄存器的地址ldr r0, =pWTCON//将R1寄存器清0mov r1, #0x0//将看门狗寄存器清0,即将看门狗禁止,包括定时器定时,溢出中断及溢出复位等str r1, [r0]/** mask all IRQs by setting all bits in the INTMR - default*///设R1寄存器为0xFFFF FFFFmov r1, #0xffffffff//读取中断屏蔽寄存器的地址ldr r0, =INTMSK//将中断屏蔽寄存器中的位全设1,屏蔽所有中断str r1, [r0]//# define INTSUBMSK_val 0xffff//设R1寄存器为0xFFFFldr r1, =INTSUBMSK_val//读取辅助中断屏蔽寄存器的地址ldr r0, =INTSUBMSK//将辅助中断屏蔽寄中的11个中断信号屏蔽掉,本人觉得INTSUBMS_val应设成7ff str r1, [r0]//# define LOCKTIME 0x4c000000//读取PLL锁频计数器寄存器地址到R0中ldr r0,=LOCKTIME//将R1设为0x00FF FFFFldr r1,=0xffffff//M_LTIME为最大的0xFFF//U_LTIME为最大的0xFFFstr r1,[r0] ;0xfff=4096>1800,远远满足锁定要求/* FCLK:HCLK:PCLK = 1:2:4 *//* default FCLK is 120 MHz ! *///# define CLKDIVN 0x4C000014 /* clock divisor register *///读取时钟分频寄存器的地址ldr r0, =CLKDIVN//# define CLKDIVN_val 7 /* FCLK:HCLK:PCLK = 1:3:6 *///将R1设为0x7mov r1, #CLKDIVN_va//PDIVN - 1: PCLK has the clock same as the HCLK/2.//HDIVN - 11 : HCLK = FCLK/3 when CAMDIVN[8] = 0.// HCLK = FCLK/6 when CAMDIVN[8] = 1.str r1, [r0]/* Make sure we get FCLK:HCLK:PCLK = 1:3:6 *///# define CAMDIVN 0x4C000018//读取摄像头时钟分频寄存器的地址ldr r0, =CAMDIVN//将R1设为0mov r1, #0//将摄像头时钟分频寄存器清0str r1, [r0]/* Clock asynchronous mode *///MRC p15, 0, Rd, c1, c0, 0 ; read control register//读取控制寄存器中的值到R1中mrc p15, 0, r1, c1, c0, 0 ;将协处理器p15的寄存器c1和c0的值传到arm处理器的R1寄存器中//31 iA bit Asynchronous clock select//30 nF bit notFastBus selectorr r1, r1, #0xc0000000 ;将最高两位置1//MCR p15, 0, Rd, c1, c0, 0 ; write control register//将R1中的值写到控制寄存器中mcr p15, 0, r1, c1, c0, 0 将arm的寄存器R1的32位数据传到协处理器p15的两个16位寄存器c1和c0//# define UPLLCON 0x4c000008//读取UPLL设置寄存器的地址到R0中ldr r0,=UPLLCON//# define UPLLCON_val ((60ldr r1,=UPLLCON_val//将R1中的值写入UPLL设置寄存器中str r1,[r0]//ARM920T为5级流水线,需要至少5个周期来让指令生效nopnopnopnopnopnopnopnop//读取MPLL设置寄存器的地址到R0中ldr r0,=MPLLCON//# define MPLLCON_val ((184ldr r1,=MPLLCON_val//将R1中的值写入MPLL设置寄存器中str r1,[r0]#define GPJCON 0x560000D0#define GPJDAT 0x560000D4#define GPJUP 0x560000D8//跳转到cpu_init_crit处执行//并将下一条指令的地址写入LR寄存器中bl cpu_init_critcpu_init_crit在cpu/arm920t/start.S中代码如下:cpu_init_crit:/** flush v4 I/D caches*///将R0寄存器置0mov r0, #0//Invalidate ICache and DCache SBZ MCR p15,0,Rd,c7,c7,0 //禁止指令和数据cachemcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache *///Invalidate TLB(s) SBZ MCR p15,0,Rd,c8,c7,0mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB *//** disable MMU stuff and caches*///MRC p15, 0, Rd, c1, c0, 0 ; read control registermrc p15, 0, r0, c1, c0, 0//清除[8] [9] [13] 这3个位//8 - System protection//9 - ROM protection//13 - Base location of exception registers - 0 = Low addresses = 0x00000000. bic r0, r0, #0x00002300 // clear bits 13, 9:8 (--V- --RS)//清除[0] [1] [2] [7] 这4个位// 0 - MMU enable - 0 = MMU disabled.// 1 - Alignment fault enable - 0 = Fault checking disabled.// 2 - DCache enable - 0 = DCache disabled.// 7 - Endianness - 0 = Little-endian operation.bic r0, r0, #0x00000087 // clear bits 7, 2:0 (B--- -CAM)//设置位[1]为真// 1 - Alignment fault enable - 1 = Fault checking enabled.orr r0, r0, #0x00000002 // set bit 2 (A) Align//设置位[12]为真//12 - ICache enable - 1 = ICache enabled.orr r0, r0, #0x00001000 // set bit 12 (I) I-Cache//MCR p15, 0, Rd, c1, c0, 0 ; write control registermcr p15, 0, r0, c1, c0, 0//将返回地址保存到IP中mov ip, lr//跳转到lowlevel_init中执行bl lowlevel_initcpu_init_crit在cpu/arm920t/start.S中代码如下:.globl lowlevel_init//读取下面标号为SMRDATA处的地址到R0中ldr r0, =SMRDATA//读取上面标号为_TEXT_BASE处的地址内容到R1中//也就是取得TEXT_BASE的值到R1中ldr r1, _TEXT_BASE//计算SMRDATA的相对地址保存到R0中//SMRDATA为虚拟地址,而TEXT_BASE为虚拟地址的起始地址//而现在Uboot的起始地址并不为虚拟地址//TEXT_BASE为0x33F8 0000,SMRDATA为0x33F8 06C8//而现在程序运行在起始地址为0x0000 0000的地方//所以需要计算以0x0000 0000为标准的相对地址sub r0, r0, r1//取得带宽与等待状态控制寄存器地址到R1中ldr r1, =BWSCON /* Bus Width Status Controller *///一共需要设置13个寄存器,每个寄存器4字节add r2, r0, #13*40://读取R0所指的项的值到R3中后R0自加4字节ldr r3, [r0], #4//将R3中的值保存到R1所指的地址中后R1自加4字节str r3, [r1], #4//比较R0和R2是否相等,相等则说明13个寄存器全部设置完毕cmp r2, r0//不等则跳转到上面标号为0处的地址继续执行bne 0b//跳回到返回地址中继续执行mov pc, lr.ltorg/* the literal pools origin */SMRDATA:.word(0+(B1_BWSCON4)+(B2_BWSCON8)+(B3_BWSCON12)+(B4_BWSCON16)+( B5_BWSCON20)+(B6_BWSCON24)+(B7_BWSCON28)).word((B0_Tacs13)+(B0_Tcos11)+(B0_T acc8)+(B0_Tcoh6)+(B0_T ah4)+(B0_T acp2) +(B0_PMC)).word((B1_Tacs13)+(B1_Tcos11)+(B1_T acc8)+(B1_Tcoh6)+(B1_T ah4)+(B1_T acp2) +(B1_PMC)).word((B2_Tacs13)+(B2_Tcos11)+(B2_T acc8)+(B2_Tcoh6)+(B2_T ah4)+(B2_T acp2) +(B2_PMC)).word((B3_Tacs13)+(B3_Tcos11)+(B3_T acc8)+(B3_Tcoh6)+(B3_T ah4)+(B3_T acp2) +(B3_PMC)).word((B4_Tacs13)+(B4_Tcos11)+(B4_T acc8)+(B4_Tcoh6)+(B4_T ah4)+(B4_T acp2) +(B4_PMC)).word((B5_Tacs13)+(B5_Tcos11)+(B5_T acc8)+(B5_Tcoh6)+(B5_T ah4)+(B5_T acp2) +(B5_PMC)).word ((B6_MT15)+(B6_Trcd2)+(B6_SCAN)).word ((B7_MT15)+(B7_Trcd2)+(B7_SCAN)).word ((REFEN23)+(TREFMD22)+(Trp20)+(Trc18)+(Tchr16)+REFCNT).word 0x32.word 0x30.word 0x30执行mov pc, lr后将返回到cpu_init_crit中剩下来还有2条指令//恢复返回地址到LRmov lr, ip//跳转到返回地址mov pc, lr执行完毕之后将返回到start_code中执行接下来的代码代码如下://#define GPJCON 0x560000D0//取得J端口控制寄存器的地址到R0中LDR R0, = GPJCON//将R1设置为0x1 5555LDR R1, = 0x15555//将R1中的值保存到J端口控制寄存器//GPJ0 - 01 - Output//GPJ1 - 01 - Output//GPJ2 - 01 - Output//GPJ3 - 01 - Output//GPJ4 - 01 - OutputSTR R1, [R0]//#define GPJUP 0x560000D8//取得J端口上拉功能寄存器的地址到R0中LDR R0, = GPJUP//将R1设置为0x1FLDR R1, = 0x1f//将R1中的值保存到J端口上拉功能寄存器//禁止GPJ0 - GPJ4的上拉功能STR R1, [R0]//#define GPJDAT 0x560000D4//取得J端口数据寄存器的地址到R0中LDR R0, = GPJDAT//将R1设为0x0LDR R1, = 0x00//将R1中的值保存到J端口数据寄存器//将J端口数据寄存器清0STR R1, [R0]//下面是NAND数据拷贝过程//relocate:copy_myself://#define S3C2440_NAND_BASE 0x4E000000//取得Nand Flash设置寄存器的地址mov r1, #S3C2440_NAND_BASE//将R2设为0xFFF0ldr r2, =0xfff0 // initial value tacls=3,rph0=7,rph1=7 //#define oNFCONF 0x00//读取Nand Flash设置寄存器中的值到R3中ldr r3, [r1, #oNFCONF]//将R3或上R2后保存到R3中orr r3, r3, r2//将R3中的值保存到Nand Flash设置寄存器中//TWRPH0 - 111 - Duration = HCLK * (TWRPH0 + 1) //TACLS - 11 - Duration = HCLK * TACLSstr r3, [r1, #oNFCONF]//#define oNFCONT 0x04//读取Nand Flash控制寄存器中的值到R3中ldr r3, [r1, #oNFCONT]//将R3的[0]位置1orr r3, r3, #1 // enable nand controller//将R3中的值保存到Nand Flash控制寄存器中//Mode - 1:Nand Flash Controller Enablestr r3, [r1, #oNFCONT]//读取虚拟起始地址到R0中ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot *///预留malloc所需要的空间sub r0, r0, #CFG_MALLOC_LEN /* malloc area *///预留bdinfo所需要的空间sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo *///预留中断和快速中断向量表空间sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)//预留12字节给中断栈sub sp, r0, #12 /* leave 3 words for abort-stack */// copy u-boot to RAM//读取虚拟起始地址到R0中,作为目标地址ldr r0, _TEXT_BASE//将R1设为0,作为源地址mov r1, #0x0//将UBOOT大小的值保存在R2中,作为数据大小mov r2, #CFG_UBOOT_SIZE//跳转到nand_read_ll处执行//并将下一条指令的地址保存在LR中bl nand_read_llnand_read_ll的原型为int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) 之前设置的R0 R1 R2为它的3个参数R0 - bufR1 - start_addrR2 - sizenand_read_ll的代码在cpu/arm920t/s3c24x0/nand_read.c中int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) {int i, j;//检测源地址和大小是否在NandFlash的边界上if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) //不在边界上则返回-1表示出错return -1; /* invalid alignment *//* chip Enable */// #define nand_select() (NFCONT &= ~(1//置NAND Flash控制寄存器中除Reg_nCE外所有的位为1//Reg_nCE - NAND FLASH Memory nFCE signal control//0 - Force nFCE to low (Enable chip select)nand_select();// #define nand_clear_RnB() (NFSTAT |= (1//置NAND Flash操作状态寄存器中的RnB_TransDetect位为1//When RnB low to high transition is occurred, this value set and issue interrupt if enabled.//To clear this value write '1'//1: RnB transition is detectednand_clear_RnB();for (i=0; i10; i++);//从源地址的首地址开始历便所要拷贝的数据大小for (i=start_addr; i (start_addr + size);){//检测地址是否在NAND Flash的边界上if (start_addr % NAND_BLOCK_SIZE == 0){//检测是否为坏块if (is_bad_block(i)){/* Bad block *///向后延伸一个存储块i += NAND_BLOCK_SIZE;size += NAND_BLOCK_SIZE;//跳到下一块continue;}}j = nand_read_page_ll(buf, i);//指向下一块i += j;buf += j;// LED_FLASH();}/* chip Disable */// #define nand_deselect() (NFCONT |= (1//置Reg_nCE位为1//NAND Flash Memory nFCE signal control//1: Force nFCE to High(Disable chip select)nand_deselect();return 0;}nand_read_ll将Uboot从NAND中拷贝到RAM中拷贝完成后将返回到start_code接下来的代码如下://检测R0是否为0,R0为nand_read_ll的返回值tst r0, #0x0//为0则说明无错,跳转到ok_nand_read处执行beq ok_nand_readok_nand_read://将R0设为0mov r0, #0//ldr r1, =0x33f00000//将R1设为虚拟地址起始处ldr r1, _TEXT_BASE//检测0x400个字节mov r2, #0x400 // 4 bytes * 1024 = 4K-bytesgo_next://读取R0处地址的数据到R3中//然后R0自加4字节ldr r3, [r0], #4//读取R1处地址的数据到R4中//然后R1自加4字节ldr r4, [r1], #4//比较R3和R4的数据是否相等//也就是检测Boot Internal SRAM和RAM中的数据是否相等//以保证数据无错teq r3, r4//不等则跳转到notmatchbne notmatch//相等则R2自减4subs r2, r2, #4//当R2为0则跳转到done_nand_readbeq done_nand_read//R2不为0则跳转回go_next继续检测bne go_nextdone_nand_read:LDR R0, = GPJDATLDR R1, = 0x2STR R1, [R0]stack_setup://读取虚拟起始地址到R0中ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ //预留malloc所需要的空间sub r0, r0, #CFG_MALLOC_LEN /* malloc area *///预留bdinfo所需要的空间sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo *///预留中断和快速中断向量表空间sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)//预留12字节给中断栈sub sp, r0, #12 /* leave 3 words for abort-stack */clear_bss://读取BSS段的起始地址ldr r0, _bss_start /* find start of bss segment *///读取BSS段的结束地址ldr r1, _bss_end /* stop here *///将R2设为0x0mov r2, #0x00000000 /* clear */clbss_l://将R2中的值保存在R0所指的地址str r2, [r0] /* clear loop... *///R0自加4字节add r0, r0, #4//比较R0和R1是否相等cmp r0, r1//不等则说明清0还没结束ble clbss_lLDR R0, = GPJDATLDR R1, = 0x1STR R1, [R0]//跳转到start_armboot处执行ldr pc, _start_armboot_start_armboot: .word start_armboot这里start_armboot是一个绝对地址,在朗成所修改的这个Uboot中为0x33F8 13F4 执行ldr pc, _start_armboot之后将会跳到RAM中的绝对地址继续执行整理了一个流程图,分为3个存储器:1 Boot Internal SRAM , 接在BANK0,起始地址为0x02 RAM , 接在BANK6,起始地址为0x3000 00003 NAND FLASH,为单独寻址流程如下图:红字为流程序号:1. 首先将NAND FLASH中的前0x1000字节内容拷贝到Boot Internal SRAM中2. 从Boot Internal SRAM的0x0地址处开始执行指令3. 将Uboot从Flash拷贝到RAM中4. 执行ldr pc, _start_armboot从Boot Internal SRAM中跳转到RAM中的绝对地址0x33F8 13F4处继续执行。

U-boot2009.08基本的寄存器设置

U-boot2009.08基本的寄存器设置

嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。

一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。

如有错误之处,谢请指正。

∙共享资源,欢迎转载:一、移植环境∙主机:VMWare--Fedora 9∙开发板:Mini2440--64MB Nand,Kernel:2.6.30.4∙编译器:arm-linux-gcc-4.3.2.tgz∙u-boot:u-boot-2009.08.tar.bz2二、移植步骤本次移植的功能特点包括:∙支持Nand Flash读写∙支持从Nor/Nand Flash启动∙支持CS8900或者DM9000网卡∙支持Yaffs文件系统∙支持USB下载(还未实现)1.了解u-boot主要的目录结构和启动流程,如下图。

u-boot的stage1代码通常放在cpu/xxxx/start.S文件中,他用汇编语言写成; u-boot的stage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。

各个部分的流程图如下:2. 建立自己的开发板项目并测试编译。

目前u-boot对很多CPU直接支持,可以查看board目录的一些子目录,如:board/samsung/目录下就是对三星一些ARM处理器的支持,有smdk2400、smdk2410和smdk6400,但没有2440,所以我们就在这里建立自己的开发板项目。

1)因2440和2410的资源差不多,主频和外设有点差别,所以我们就在board/samsung/下建立自己开发板的项2)因2440和2410的资源差不多,所以就以2410项目的代码作为模板,以后再修改3)修改u-boot跟目录下的Makefile文件。

查找到smdk2410_config的地方,在他下面按照smdk2410_config到此为止,u-boot对自己的my2440开发板还没有任何用处,以上的移植只是搭建了一个my2440开发板u-boot 的框架,要使其功能实现,还要根据my2440开发板的具体资源情况来对u-boot源码进行修改。

终端乱码的终极解决方案

终端乱码的终极解决方案

终端乱码的终极解决方案初入linux的程序员们,经常会受到乱码的问候。

可谓“始乱终弃”。

因为乱码,并且最终放弃了linux的不在少数。

好吧,言归正传,先看看各类乱码是怎么形成的。

中文字符乱码这种情况一般是安装了中文控制端,但没有启用中文应用造成的。

只需要启动相应软件即可,如zhcon。

或者是启用了相应软件,但字符集不对,需设置相应字符集,例如export LANG=zh_CN.UTF-8ORACLE安装界面乱码虽说ORACLE支持多国语言,会根据环境变量自动选择字符集,但中文安装好像还有问题,不过10.2以后的版本好像没有该问题了,具体可以执行命令export LANG=en_US来设置为英文字符集环境英文字符乱码一般该字符乱码多出现在cat了二进制的文件时,因为二进制文件中多有控制码,会导致终端界面乱码,通常解决方法是用reset终端复位命令解决问题其他伪终端乱码有时是通过SSH进入远程LINUX服务器时,cat一个core文件,并且用reset命令都不能成功,怎么办?很简单,看以下试验,首先cat一个python的编译文件oracle@linux-suse:~> cat fibo.pycm?{?鯡c@sdZdZdS(cCs:d\}}x’||jo|G|||}}qWdS(Nii(ii(tatbtn(RRR((tfibo.pytfibscCsIg}d\}}x0||jo”|i||||}}qW|S(Nii(ii(tresultRRRtappend(RRRR((Rtfib2 sN(RR(RR((Rt?s oracle@linux-suse:~> VT102VT102\-bash: VT102VT102: command not foundoracle@linux-suse:~>在SSH终端上看到是的乱码,提示符都是乱的,可以用以下命令恢复oracle@linux-suse:~> tput sgr0乱码问题产生的原因是SSH的问题,因为在其他终端下,cat用样一个文件,不会产生乱码,于是试验乱码产生的原因oracle@linux-suse:~> ^N只要用ctrl+v,ctrl+n就使用屏幕乱码,当然恢复后再试验oracle@linux-suse:~> echo -e ‘\xe’屏幕再次乱码,好,再恢复oracle@linux-suse:~> echo -e ‘\xf’以上是需要盲打的,因为屏上看到的是乱码,最终问题产生的原因是十六进制字符E 产生的,解决也很简单,十六进制字符F即可。

串口接收数据乱码的原因总结

串口接收数据乱码的原因总结

串口接收数据乱码的原因总结串口接收数据乱码的原因总结串口是一种通信接口,可以用于通过连接电脑或其他设备来进行数据传输。

在使用串口进行数据传输时,有时会出现数据乱码的问题,这可能会导致数据传输的不准确或者失败。

那么,究竟是什么原因导致了串口接收数据乱码呢?1. 波特率设置错误串口传输时,双方必须采用相同的波特率才能实现正常通信。

如果串口接收方将波特率设置错误,就会导致数据传输出现错误,这也是数据乱码出现的主要原因之一。

2. 校验位设置错误串口传输中,校验位是用于检验数据传输的正确性和完整性。

如果校验位设置错误,就会导致数据传输过程中出现错误,从而出现了数据乱码。

3. 数据位设置错误串口传输时,数据位是指每次传输的数据位数,需要与接收方的数据位设置一致,否则传输的数据可能会出现乱码。

4. 停止位设置错误串口传输中,停止位是用于标志数据传输完成的信号。

如果停止位设置错误,就会导致数据传输不完整,也就是出现了数据乱码。

5. 串口驱动程序问题在使用串口进行数据传输时,串口驱动程序也是一个非常重要的因素。

如果串口驱动程序出现问题,就可能导致串口接收数据过程中出现乱码等问题。

6. 线路连接问题串口线路连接质量也是决定传输质量的一个关键因素。

如果线路质量差,或者发生短路等问题,就可能导致数据传输过程中出现乱码等错误。

总的来说,串口接收数据乱码的原因比较多样化,需要从多个方面考虑问题。

在使用串口进行数据传输时,我们需要仔细检查各项设置,确保所有参数都设置正确,并且注意检查线路连接质量和串口驱动程序是否正常工作。

只有保证各个方面都正常,才能确保串口数据传输的正确性和可靠性。

深度揭秘乱码问题背后的原因及解决方式

深度揭秘乱码问题背后的原因及解决方式

深度揭秘乱码问题背后的原因及解决方式做Web开发的IT人,如果工作中没遇到过几次乱码的问题,估计都不好意思说自己是开发工程师。

:)而乱码问题也是各种各样,有保存到数据库中是乱码的,有在服务端接收到参数是乱码的,有在后台返回到客户端时候出现乱码的……这形形色色的乱码问题,如果处理起来不得要领,着实会让开发人员费不少工夫。

本文,将从乱码的产生原因,应用服务器内部对参数的处理各方面详解原理及解决方案。

1编码在开发中,只要有IO的地方,都会涉及到编码。

例如下面的代码:System.out.println( 'Hello 中国' );你猜这个会输出什么呢?这个其实是和你的文件编码有很大关系的,可能会输出Hello 中国也有可能会输出成下面这个样子Hello你可以改动IDE中的文件编码重复试几次。

那为什么会产生这个原因呢?我们来看这行代码执行过程中的调用栈:我们看到,简单的一句输出,也是有编码的。

看看CharsetEncoder,实现类真多啊再比如我们都无比熟悉的equals方法,先声明常量STR如下:之后,代码中有如下的逻辑你认为,这个时候会有输出吗?答案是看情况!当我把Constant类以UTF-8为编码保存后,把包含if逻辑的代码以GBK保存之后,equals执行时比较的两个参数就变成了下面的样子:所以这一定是不会为true的。

这也是乱码产生的原因,原因即解码时采用的encoding与编码时用的encoding不一致所造成的。

2应用服务器内的乱码在Web应用中,乱码的成因和上述分析是一致的。

我们向应用服务器发送一个这样的请求:http://localhost:8080/test/servlet?abc=你好服务器用request.getParameter('abc')来获取,这个时候有乱码问题吗?答案依然是It depends.这次的看情况是要看哪些情况呢?有以下这些。

SpringBoot中文乱码问题解决方案汇总

SpringBoot中文乱码问题解决方案汇总

SpringBoot中⽂乱码问题解决⽅案汇总使⽤ Spring Boot 开发,对外开发接⼝供调⽤,传⼊参数中有中⽂,出现中⽂乱码,查了好多资料,总结解决⽅法如下:第⼀步,约定传参编码格式不管是使⽤httpclient,还是okhttp,都要设置传参的编码,为了统⼀,这⾥全部设置为utf-8第⼆步,修改application.properties⽂件增加如下配置:spring.http.encoding.force=truespring.http.encoding.charset=UTF-8spring.http.encoding.enabled=trueserver.tomcat.uri-encoding=UTF-8此时拦截器中返回的中⽂已经不乱码了,但是controller中返回的数据依旧乱码。

第三步,修改controller的@RequestMapping修改如下:produces="text/plain;charset=UTF-8"这种⽅法的弊端是限定了数据类型,继续查找资料,在stackoverflow上发现解决办法,是在配置类中增加如下代码:@Configurationpublic class CustomMVCConfiguration extends WebMvcConfigurerAdapter {@Beanpublic HttpMessageConverter<String> responseBodyConverter() {StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));return converter;}@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {super.configureMessageConverters(converters);converters.add(responseBodyConverter());}@Overridepublic void configureContentNegotiation(ContentNegotiationConfigurer configurer) {configurer.favorPathExtension(false);}}便可以解决SpringBoot的中⽂乱码问题了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

S3C2440始终设置问题
2440的PLL分为两种,MPLL和UPLL,MPLL用来做系统时钟,UPLL则是USB时钟(必须为48M),两种时钟的计算方法一样:
M pll=(m×F osc×2)÷(p×2^s)记住是2的s次幂2410 不必乘2 m=MDIV+8
p=PDIV+2
s=SDIV
U pll=(m×F osc×2)÷(p×2^s)
这里的m,p,s 分别都在MPLLCON 寄存器的[19:12],[9:4],[1:0]或UPLLCON寄存器的[19:12],[9:4],[1:0]里进行设置,他们的取值详见
官方的推荐表:
MPLLCON和UPLLCON的值根据上面的两个公式计算而来,而这两个寄存器的设置值决定了系统的工作主频,和USB的主时钟分频前的频率。

如果用到USB或串口的话,那就需要小心的设置CLKDIVN寄存器了,这个寄存器的DIVN_UPLL位决定了USB的时钟,且必须为48M,例如:
你的UPLL设置为48M时则不需要分频,DIVN_UPLL位为0就可以了,反之,如果你的UPLL设置为96M时,为保持USB时钟为48M,这里的DIVN_UPLL必须设置为1.
HDIVN设置则要稍微复杂些,需要根据CAMDIVN[9]来综合决定,原则是首先确定你想要的HCLK频率,然后再结合系统的频率限制合理的来设置。

PDIVN设置直接决定你的串口能否正常工作了,同样举个例子:当前系统的主频为MPLL 为400M ,UPLL为48M,CAMDIVN[9]位为0,那么想得到115200的波特率,CLKDIVN寄存器应该设置为多少?首先可以确定DIVN_UPLL位为0,解释见上面,接下来确定HDIVN 和PDIVN了,s3c24x0的波特率计算公式为
UBRDIV=PCLK/(baudrate×16)-1
波特率直接和PCLK有关,假设UBRDIV设置为0x1A,则PCLK为50M,是FCLK的1/8,所以HDIVN=2 PDIVN=1。

在SMDK2410基础上进行2440的移植时钟部分要注意两个地方,第一个是start.s里关于时钟的设置,还有一个是speed.c里get_HCLK 函数和get_PLLCLK函数。

需要你根据相应的时钟寄存器进行修改。

相关文档
最新文档