⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2410lib.c

📁 开发环境为arm公司的ads,这个bootloader适用于arm920t核心的三星公司的s3c2410处理器.
💻 C
📖 第 1 页 / 共 2 页
字号:
	rTCON &= ~(1<<20);
	rTCON |= (1<<20);	//停止再启动,重装初值,减计数
	
	while(ms--) {
		while(rTCNTO4>=i);
		while(rTCNTO4<i);
	}
}
/***************************************************************************************************/
/************************下面是串口通讯相关函数*****************************************************/
/***************************************************************************************************/

/***************************************************************************
Function name: SerialSwitch
Parameter    : port : 串口选择参数,0:串口1 1:串口2	
Description  : 进行串口切换
Return	     : 返回串口切换的参数,是串口1还是串口2
Argument     : 
Autor & date :
****************************************************************************/
static U16 SerialPortSel;

U16 SerialSwitch(U16 port)
{
#ifdef	SERIAL_PORTS_SWITCH
//	U16 old_sel = SerialPortSel;
	
	SerialPortSel = port?1:0;
#else
	SerialPortSel = 0;
#endif
	return SerialPortSel;
}

/***************************************************************************
Function name: SerialChgBaud
Parameter    : baud	: 串口波特率参数
Description  : 设置串口的波特率
Return	     : void
Argument     : 常用串口波特率范围:2400,4800,9600,19200,38400,115200等		
Autor & date :
****************************************************************************/
void SerialChgBaud(U32 baud)
{
	U32 mclk =  GetMasterClock();
	
	rUFCON0 = 0x0;		//FIFO disable
	rUFCON1 = 0x0;
	rUMCON0 = 0x0;
	rUMCON1 = 0x0;

//UART0
//	rULCON0  = 0x7;		//Normal,No parity,2 stop,8 bit
	rULCON0  = 0x3;		//Normal,No parity,1 stop,8 bit
	rUCON0   = 0x245;	//rx=edge,tx=level,disable timeout int.,enable rx error int.,normal,interrupt or polling
	rUBRDIV0 = ((int)(mclk/16./baud + 0.5) -1);

//UART1
//	rULCON1  = 0x7;		//Normal,No parity,2 stop,8 bit
	rULCON1  = 0x3;
	rUCON1   = 0x245;
	rUBRDIV1 = ((int)(mclk/16./baud + 0.5) -1);
}

/***************************************************************************
Function name: SerialTxChar
Parameter    : data	:要发送的数据
Description  : 主要进行串口发送
Return	     : void
Argument     : 通过SerialPortSel变量来选择是哪个串口发送数据	
Autor & date :
****************************************************************************/
void SerialTxChar(char data)
{
	if(SerialPortSel) {
		if(data=='\n') {
			while(!(rUTRSTAT1 & 0x4));
	    	//Delay(1);	//because the slow response of hyper_terminal 
			WrUTXH1('\r');
		}
		while(!(rUTRSTAT1 & 0x4)); //Wait until THR is empty.
//		Delay(1);
		WrUTXH1(data);
    } else {
		if(data=='\n') {
			while(!(rUTRSTAT0 & 0x4));
			//Delay(1);	//because the slow response of hyper_terminal 
			WrUTXH0('\r');
		}
		while(!(rUTRSTAT0 & 0x4));  //Wait until THR is empty.
		WrUTXH0(data);
    }
  }

/***************************************************************************
Function name: SerialRxReady
Parameter    : void
Description  : 检测串口接收缓冲区是否有数据
Return	     : 返回UTRSTATn[0]的状态
Argument     : 不管什么时候,只要接收缓冲寄存器包含有效数据,UTRSTATn[0]就
				自动被设置为1,否则为0
Autor & date :
****************************************************************************/
int SerialRxReady(void)
{
	if(SerialPortSel)
		return (rUTRSTAT1 & 0x1);	//Receive data ready
	else 
		return (rUTRSTAT0 & 0x1);	//Receive data ready
}

/***************************************************************************
Function name: SerialRxKey
Parameter    : void
Description  : 检测串口接收缓冲区是否有数据,有的话,返回缓冲区的数据
Return	     : 返回接收缓冲区的数据或则0
Argument     : 不管什么时候,只要接收缓冲寄存器包含有效数据,UTRSTATn[0]就
				自动被设置为1,否则为0
Autor & date :
****************************************************************************/
char SerialRxKey(void)
{
	if(SerialPortSel) {
		if((rUTRSTAT1 & 0x1)) //Receive data ready
			return RdURXH1();
	} else {
		if((rUTRSTAT0 & 0x1)) //Receive data ready
			return RdURXH0();
	}
	return 0;
}

/***************************************************************************
Function name: SerialTxString
Parameter    : *s : 要发送的字符串变量
Description  : 向串口发送字符串
Return	     : void
Argument     : 
Autor & date :
****************************************************************************/
void SerialTxString(char *s)
{
	 while(*s)
		SerialTxChar(*s++);
}

/***************************************************************************
Function name: putch
Parameter    : ch : 要发送的数据
Description  : 向串口发送一个数据
Return	     : void
Argument     : 
Autor & date :
****************************************************************************/
void putch(char ch)
{
	
	SerialTxChar(ch);

}

/***************************************************************************
Function name: puts
Parameter    : *str : 要发送的字符串指针变量
Description  : 向串口发送字符串
Return	     : void
Argument     : 
Autor & date :
****************************************************************************/
void puts(char *str)
{
	SerialTxString(str);
	
}

/***************************************************************************
Function name: kbhit
Parameter    : void
Description  : 检测串口接收缓冲区是否有数据
Return	     : 有,返回1,否返回0
Argument     : 
Autor & date :
****************************************************************************/
int kbhit(void)
{
	if(SerialRxReady())
		return 1;
	return 0;
}

/***************************************************************************
Function name: printf
Parameter    : *fmt : 数据显示的格式
Description  : 根据提供的格式显示变量的数值
Return	     : void
Argument     : 调用了ADS的库函数
Autor & date :
****************************************************************************/
//If you don't use vsprintf(), the code size is reduced very much.
typedef int *__va_list[1];
int vsprintf(char * /*s*/, const char * /*format*/, __va_list /*arg*/);

void printf(char *fmt, ...)
{
	va_list ap;
	char string[1024];
	
	va_start(ap,fmt);
	vsprintf(string,fmt,ap);
	puts(string);
	va_end(ap);
}

/***************************************************************************
Function name: getkey
Parameter    : void
Description  : 
Return	     : 如果串口接收缓冲区有数据,就返回数据,否则返回0
Argument     : 
Autor & date :
****************************************************************************/
int getkey(void)
{
	int c;
	
	c = SerialRxKey();
	if(c)
		return c;
	return 0;
//	return GetScanKey();
}

/***************************************************************************
Function name: getch
Parameter    : void
Description  : 等待从串口接收一个数据,否则一直循环
Return	     : 返回接收到的数据
Argument     : 
Autor & date :
****************************************************************************/
char getch(void)
{
	int c;
	
	while(1) {
		c = getkey();
		if(c) {
			//printf("get key!\n");
			return c;
		}
	}
	//return SerialRxChar();
}

/***************************************************************************
Function name: memcpy
Parameter    : *s1:目的地址 *s2:源地址 n:要拷贝的数据的长度
Description  : 将长度为n的数据拷贝从源地址拷贝到目的地址
Return	     : void
Argument     : 
Autor & date :
****************************************************************************/
void memcpy(void *s1, const void *s2, int n)
{
	int i;

	for (i = 0; i < n; i++)
		((char *)(s1))[i] = ((const char *)(s2))[i];
}

/***************************************************************************
Function name: strlen
Parameter    : *s:字符串指针
Description  : 计算字符串的长度
Return	     : void
Argument     : 
Autor & date :
****************************************************************************/
int strlen(const char *s)
{
	int i = 0;

	for(; *s; s++)
		i++;
	
	return i;
}
/***************************************************************************/
unsigned short ntohs(unsigned short s)
{
	return (s >> 8) | (s << 8);
}

unsigned long ntohl(unsigned long l)
{
	return  ((l >> 24) & 0x000000ff) |
		((l >>  8) & 0x0000ff00) |
		((l <<  8) & 0x00ff0000) |
		((l << 24) & 0xff000000);
}

unsigned short htons(unsigned short s)
{
	return (s >> 8) | (s << 8);
}

unsigned long htonl(unsigned long l)
{
	return ntohl(l);
}

/***************************************************************************
Function name: MoveRun
Parameter    : void
Description  : 启动Linux
Return	     : void
Argument     : 
Autor & date :
****************************************************************************/
void MoveRun(void)
{
	
}

/*************************************************************/
static __inline void cpu_arm920_cache_clean_invalidate_all(void)
{
	__asm{
		mov	r1, #0		
		mov	r1, #7 << 5			  	/* 8 segments */
cache_clean_loop1:		
		orr	r3, r1, #63UL << 26	  	/* 64 entries */
cache_clean_loop2:	
		mcr	p15, 0, r3, c7, c14, 2	/* clean & invalidate D index */
		subs	r3, r3, #1 << 26
		bcs	cache_clean_loop2		/* entries 64 to 0 */
		subs	r1, r1, #1 << 5
		bcs	cache_clean_loop1		/* segments 7 to 0 */
		mcr	p15, 0, r1, c7, c5, 0	/* invalidate I cache */
		mcr	p15, 0, r1, c7, c10, 4	/* drain WB */
	}
}
void cache_clean_invalidate(void)
{
	cpu_arm920_cache_clean_invalidate_all();
}

static __inline void cpu_arm920_tlb_invalidate_all(void)
{
	__asm{
		mov	r0, #0
		mcr	p15, 0, r0, c7, c10, 4	/* drain WB */
		mcr	p15, 0, r0, c8, c7, 0	/* invalidate I & D TLBs */
	}
}

void tlb_invalidate(void)
{
	cpu_arm920_tlb_invalidate_all();
}

void disable_irq(void);

void call_linux(U32 a0, U32 a1, U32 a2)
{
	void (*goto_start)(U32, U32);
	cache_clean_invalidate();
	tlb_invalidate();	

	__asm{
//		mov	r0, a0//%0
//		mov	r1, a1//%1
//		mov	r2, a2//%2
		mov	ip, #0
		mcr	p15, 0, ip, c13, c0, 0	/* zero PID */
		mcr	p15, 0, ip, c7, c7, 0	/* invalidate I,D caches */
		mcr	p15, 0, ip, c7, c10, 4	/* drain write buffer */
		mcr	p15, 0, ip, c8, c7, 0	/* invalidate I,D TLBs */
		mrc	p15, 0, ip, c1, c0, 0	/* get control register */
		bic	ip, ip, #0x0001			/* disable MMU */
		mcr	p15, 0, ip, c1, c0, 0	/* write control register */
		//mov	pc, r2
		//nop
		//nop
		/* no outpus */
		//: "r" (a0), "r" (a1), "r" (a2)
	}
//	SetClockDivider(1, 1);
//	SetSysFclk(FCLK_200M);		//start kernel, use 200M
	Delay(1000);
//	disable_irq();
	goto_start = (void (*)(U32, U32))a2;//先强制a2(地址)为一个函数指针,带两个参数,用来传递
	(*goto_start)(a0, a1);	//跳到RAM内核地址
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -