NXP-UU编码

NXP-UU编码

2.UU编码方案

UUencode是源自UNIX环境的二进制到ASCII编码的一种形式。

UUencode取一个8位值,并将其转换为ASCII等效值。UUencode在三个8位数据字节的组上工作。如果数据字节不在三个一组中,必须添加填充字节。可以编码的最大数据字节数在一条数据线中是45个数据字节。每条数据行不能超过61个字符。

UUencode数据的数据行使用以下格式:

  • <字符长度><格式化字符><换行符>

    • <字符长度>是一个字符,指示在线字符长度是通过在数据字节数上加32来计算的在编码发生之前传输。
    • <格式化字符>是编码的数据字节。
    • <换行符>指示数据字节的结束。新行用、回车和换行。

3.UUencode转换

UUencode转换的流程如下:

  1. 数据被细分为3字节组,形成24比特流
  2. 然后将24比特流细分为6比特组
  3. 值0x20被添加到6位组
  4. 如果6位组的值为0x00,则会将值0x60添加到其中
  5. 计算数据字节数并将其转换为ASCII等效值

如果字节数不是三的倍数,则添加填充字节以创建三的倍数。填充的字节可以是任何值,因为解码过程丢弃填充的字节。建议使用0x00的值。例如,对于由4个字节组成的有效载荷,添加两个填充字节以创建6个字节的有效载荷。每个Uuencode行不能超过61个字符/45个数据字节。

3.1 UUencode示例–三字节数据

此示例描述如何转换由0x14、0x0F和0xA8转换为UUencode流。

第一步是将数据字节转换为24比特流。
在这里插入图片描述
24比特流被细分为6比特组。
在这里插入图片描述
将值0x20添加到6位值。结果是ASCII表中的一个字符。
对于值为0x00的6位数据,与0x20相反,将值0x60添加到其中。
在这里插入图片描述
使用ASCII表确定与编码值关联的ASCII字符。
在这里插入图片描述
计算要传输的字节数,然后将其转换为ASCII相等的数据字节由3个字节组成:0x14、0x0F和0xA8。角色长度是通过在数据字节数上加32来确定的。 对于本例字符长度为“#”。

  • 3 + 32 = 35 = 0x23 = “#”

发送到NXP控制器的线路为:

  • #%`^H<CR><LF>

3.2. UUencode示例–4字节数据

此示例描述如何转换由0x14、0x0F、0xA8和0x17转换为UUencode流。

UUencode期望数据是3的倍数。4个字节的数据用2填充0x00的数据字节,因此它是3的倍数。

第一步是将数据字节转换为24比特流。
在这里插入图片描述
24比特流被细分为6比特组。
在这里插入图片描述
将值0x20添加到6位值。结果是ASCII表中的一个字符。
对于值为0x00的6位数据,与0x20相反,将值0x60添加到其中。
在这里插入图片描述
使用ASCII表确定与编码值关联的ASCII字符。
在这里插入图片描述
计算要传输的字节数,然后将其转换为ASCII相等的数据字节由四个字节组成,即0x14、0x0F、0xA8和0x17。这个字符长度是通过在数据字节数上加32来确定的。为此

例如,字符长度为“$”。

  • 4 + 32 = 36 = 0x24 = “$”
  • x(字符的长度) + 0x20 = 字符长度

发送到NXP控制器的线路为:

  • $%`^H%P``

4.计算校验和

校验和是传输字节的总和。读/写时需要校验和发出命令。要发送到控制器的校验和为十进制形式。

例如,如果由0x14、0x0F和0xA8组成的数据字节要发送到

NXP控制器,校验和为:

  • 0x14 + 0x0F + 0xA8 = 0xCB

0xCB的十进制等效值为203。编号203被发送到NXP控制器,作为校验和。

发送到NXP控制器的线路为:

  • 203<CR><LF>

5. UART ISP示例

  • 对于以下ISP示例,使用的主机是运行TeraTerm的Windows 7系统。
  • UART端口设置为9600,8,N,1,XON/XOFF。
  • 所使用的测试板是带有LCP1114/302的LPCXpresso基板。
  • 所有UART ISP命令都应作为单个ASCII字符串发送。字符串需要以回车(CR)和换行(LF)控制字符终止。额外并且忽略<LF>字符。所有ISP响应均发送为终止ASCII字符串。数据以UU编码格式发送和接收。所有其他命令和响应采用ASCII格式。

5.1. ISP初始化

控制器必须首先进入ISP模式。对于LCP1114,这是通过在复位期间使PIO0_1引脚接地。ISP模式初始化后,主机准备用于ISP控制的控制器。

步骤如下:

  1. 主机发送ASCII字符“?”
  2. 控制器响应“已同步”
  3. 主机用“已同步”来确认这一点
  4. 控制器响应“OK”
  5. 主机现在发送晶体的频率(kHz)。例如发送“12000”对于12 MHz的晶体
  6. 控制器响应“OK”
  7. 如果需要,主机现在可以设置新的波特率

图. UART ISP初始化
在这里插入图片描述

5.2. 阅读记忆

从RAM/闪存中读取的命令格式如下:

  • R<地址><字节数>

    • <地址>是所需的十进制地址。地址必须是单词边界。
    • <字节数>是所需的字节。字节数必须是4的倍数。

当发出读取时,控制器用请求的数据进行响应,该数据编码在UUencode格式以及所请求数据的校验和。

校验和是在发送请求量的数据或20 UU编码后发送的行,以先到者为准。校验和是通过将原始数据(之前UU编码)字节,并且在发送20个UU编码行之后被重置。的长度任何UU编码行不应超过61个字符(字节),即它可以容纳45个数据字节。当数据适合小于20个UU编码行时,校验和为实际发送的字节数。

例如,要从地址0x10000000读取4个字节的数据,请执行以下操作顺序发生:

  1. 主机发送命令“R 268435456 4”
  2. 控制器通过返回代码、数据和校验和进行响应
  3. 如果校验和正确,主机将发送“OK”。如果校验和不正确,则发出“RESEND”命令,以便控制器可以重新发送数据

图. UART ISP从内存读取
在这里插入图片描述

5.3. 写入RAM

写入RAM的命令格式如下:

  • W<起始地址><字节数>

    • <起始地址>是所需的十进制地址。地址必须是单词边界。
    • <字节数>是所需的字节。字节数必须是4的倍数。

例如,将0x14、0x0F、0xA8和0x17的值写入0x10000000,则出现以下顺序:

  1. 主机发送命令“W 268435456 4”
  2. 控制器以返回代码进行响应
  3. 主机以UUencode格式发送数据,“$%`^H%P``”
  4. 主机发送校验和“226”
  5. 如果校验和与数据匹配,控制器将以“OK”作为响应。如果校验和不匹配,则向主机发回“RESEND”

图. UART ISP写入RAM
在这里插入图片描述

5.4.将RAM复制到闪存

将数据从RAM复制到闪存的命令格式如下:

  • C<闪存地址><RAM地址><字节数>:

    • <闪存地址>是十进制的目标地址。目标地址应是256字节的边界。
    • <RAM地址>是以十进制表示的源地址。
    • <字节数>是所需的字节。有效值为256、512、1024和4096。

写入闪存时,以下限制适用:

  1. 将RAM复制到闪存可以写入闪存的最小数据量命令为256字节(等于一页)。
  2. 一页由16个快闪字(行)组成修改的每次闪存写入是一个闪存字(一行)。此限制来自ECC在闪存写入操作中的应用。
  3. 为了避免写入干扰(闪存固有的机制)应在同一页内连续写入16次之后执行。请注意,擦除操作会擦除整个扇区。

备注:一旦一个页面被写入16次,仍然可以写入其他页面在不执行扇区擦除的情况下(假设页面先前已被擦除)。

例如,为了在0x10000000处从RAM复制256个字节到0x00处的闪存出现以下顺序:

  1. 主机发送解锁命令“U 23130”
  2. 控制器以返回代码进行响应
  3. 主机发送Prepare Sector for write命令“P 0 0”
  4. 控制器以返回代码进行响应
  5. 主机发送复制命令“C 0 268435456 256 ”
  6. 控制器以返回代码进行响应

图.UART ISP将RAM复制到闪存
在这里插入图片描述

6. 提示和提示

UART ISP命令控制器默认情况下会回显接收到的数据。最大化UART传输的速度,回声功能可以关闭。这是通过向控制器发送a 0的命令来完成。

对于读取操作,将在每20行UUencode之后发送一个校验和。主机ISP代码应该说明这一点。对于写入操作,必须在每20个UU编码行。

RAM由ISP控制器在ISP模式下使用。避免在中使用这部分RAM ISP(如果可能的话)。请参阅控制器的用户手册,以确定RAM的块在ISP中使用。

在ISP模式下,闪存编程命令使用RAM的前32个字节。这个最大堆栈使用量为256字节,并且向下增长。

必须在进行任何闪存操作之前发出Unlock(解锁)命令。

在将RAM复制到闪存和擦除之前,必须执行“准备扇区”命令扇区命令。

7.额外资源

  1. 利用mbed平台在LPC1768上实现UART ISP http://mbed.org/cookbook/lpc-bootloader
  2. 用于LPC1100/LPC1300/LPC1700的UART ISP/LPC2000 http://sourceforge.net/projects/lpc21isp/
  3. Linux平台的UART ISP http://code.google.com/p/lpcflash/
  4. 用Python编写的UART ISP http://sourceforge.net/projects/nxpprog/
  5. 用Python为LPC2000系列编写的UART ISP http://sourceforge.net/projects/pylpctools/

8.程序设计

/**
 * ********************************************************************************************************
 * 简    述	: UU编码,将原始数据进行封装
 * 		_pbuf	: 原始缓冲数据
 * 		_len	: 数据长度
 * 		_pcode	: 发送编码函数
 * 返 回 值	: 校验值
 * ********************************************************************************************************
 */
uint32_t ulUUencode_Package(const uint8_t *_pbuf, uint16_t _len, void (*_pcode)(uint8_t *,uint16_t) )
{
	uint8_t TxBuff[64];
	uint16_t x = 0;
	uint8_t y = 0;
	uint8_t z = 0;
	uint8_t k = 0;
	uint8_t num = 0;
	uint32_t check_data = 0;
	for( x=0; x<_len; x+=45 )
	{
		k = 0;
		/* 45字节 */
		if( _len - x >= 45 )		num = 45;
		else						num = _len - x;
		TxBuff[k++] = num + 32;			/* 校验数据 */
		for( y=0; y<num; y+=3 )
		{
			TxBuff[k++] = (((_pbuf[x+y]>>2) & 0x3F) + ' ') & 0x7F;

			TxBuff[k++] = ((((_pbuf[x+y]<<4) & 0x30) | ((_pbuf[x+y+1] >> 4) & 0x0F)) + ' ') & 0x7F;

			TxBuff[k++] = ((((_pbuf[x+y+1]<<2) & 0x3C) | ((_pbuf[x+y+2] >> 6) & 0x03)) + ' ') & 0x7F;

			TxBuff[k++] = ((_pbuf[x+y+2] & 0x3F) + ' ') & 0x7F;

			for( z=1; z<=4; z++)
			{
				if( TxBuff[k-z] == ' ' ) TxBuff[k-z] = '`';
			}
		}
		TxBuff[k++] = '\r';
		TxBuff[k++] = '\n';
		_pcode( TxBuff, k );
//		HAL_Delay(1);
		delay_us( 750 );
	}
	for( x=0; x<_len; x++)
    {
        check_data += _pbuf[x];
    }
	return check_data;
}
  • 27
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值