DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 6056|回复: 5
打印 上一主题 下一主题

[转载] C8051F340 Bootloader 代码

[复制链接]
跳转到指定楼层
楼主
发表于 2011-8-16 05:23:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
鉴于大家学习方便,现给出C8051F340 Bootloader的代码架构,由于涉及商业信息,所以不能给出整个工程,请谅解!
相关文档信息,请参看blog: http://blog.ednchina.com/zhurunping/239751/message.aspx#

// 项目名称: C8051F340 BootLoader
// 版本介绍:
// 1.4.2 该程序仅作学习测试使用, 请勿用作其他.
//   介意使用内部晶振.
/** 擦除一个分区 */
#define flash_erase(addr)  D_MACRO_BEGIN \
         FLKEY = 0xA5; \
         FLKEY = 0xF1; \
         PSCTL  = 0x03; \
         *addr = 0x00; \
         PSCTL = 0x00; \
        D_MACRO_END
/** 写入Flash一个字节*/
#define flash_write(addr, x) D_MACRO_BEGIN \
         FLKEY = 0xA5; \
         FLKEY = 0xF1; \
         *(addr) = x; \
        D_MACRO_END
/** 串口查询方式发送一字节数据*/
#define Uart_PutCh(dat)   D_MACRO_BEGIN \
         SBUF1 = dat; \
         while ((SCON1&0x02) == 0); \
         SCON1 &= 0xFD; \
        D_MACRO_END
#define D_APP_START  0x0000    // APP区起始地址
#define D_APP_LIMIT  0xEE00    // APP区结束地址
#define D_RUN_ADDRESS 0xEE00    // APP运行地址(只使用3Byte)
#define D_BOOT_ADDR  0xF000    // Boot程序存储地址
#define D_BOOT_LIMIT 0xF800    // Boot区结束地址
#define D_FLASH_LIMIT 0xFA00    // FLASH可操作区结束地址

/** 本地变量*/
uint8 rst_addr[3];      // 用以保存启动向量
uint8 xdata *pwrite;     // 指向代码区的指针
uint8 code *pread;      // 指向代码区的指针
uint8 dat;
/** @func RTload
* @brief 载入函数
*/
static void
RTload(void)
{
uint8 dat, tmp[4];
uint16 i, size, dnCS, CheckSum;
Uart_Print(">Start erasing flash...\n");
/** 1. 保存boot入口地址, 最后回写 */
pread = 0;
rst_addr[0] = *pread++;
rst_addr[1] = *pread++;
rst_addr[2] = *pread++;
/** 2. 准备扇区 */
for (pwrite=0; pwrite<D_APP_LIMIT; pwrite+=0x200) { // APP区
  flash_erase(pwrite);
}
pwrite = D_RUN_ADDRESS;    // 启动参数区
flash_erase(pwrite);
Uart_Print(">Erasing complete.\n");
/** 3. 回写boot入口地址 */
PSCTL = 0x01;
pwrite = 0;
flash_write(pwrite++, rst_addr[0]);
flash_write(pwrite++, rst_addr[1]);
flash_write(pwrite++, rst_addr[2]);
/** 4. 通知主机发送代码 */
SCON1 |= B_REN1;
Uart_Print(">Please transmit bin file...\n");
/** 5. 读接收数据长度 */
for (i=0; i<4; i++) {
  while ((SCON1&0x01) == 0);
  SCON1 &= 0xFE;
  tmp = SBUF1;
}
size = ((tmp[1]<<8)+tmp[0]) - 4 - 2;
if (size > D_APP_LIMIT) {
  PSCTL = 0x00;
  Uart_Print(">Error: no enough space for your app!\n");
  return;
}
/** 6. 开始接收数据, 同时写入Flash APP区*/
CheckSum= 0;
pwrite = D_RUN_ADDRESS;    // 启动地址(3Byte)
for (i=0; i<3; i++) {
  while ((SCON1&0x01) == 0);
  SCON1 &= 0xFE;
  dat = SBUF1;
  CheckSum += dat;
  flash_write(pwrite++, dat);
}
pwrite = 3;       // 程序区
for (i=3; i<size; i++) {
  while ((SCON1&0x01) == 0);
  SCON1 &= 0xFE;
  dat = SBUF1;
  CheckSum += dat;
  flash_write(pwrite++, dat);
}
PSCTL = 0x00;       // 禁止Flash操作
/** 7. 读校验和 */
for (i=0; i<2; i++) {
  while ((SCON1&0x01) == 0);
  SCON1 &= 0xFE;
  tmp = SBUF1;
}
dnCS = (tmp[1]<<8) + tmp[0];
Uart_Print(">Transmit complete.\n");
/** 8. 校验数据*/
if (dnCS != CheckSum) {
  Uart_Print(">CheckSum error!\n");
} else {
  Uart_Print(">Programming Complete.\n");
  Uart_Print(">You have to restart the device to use the new firmware.\n");
}
}
void
main(void)
{
uint8 dat;
uint16 timeout;
void (*boot)( void);
Init_Device();       // 初始化设备
FLSCL = ((FLSCL&0xF0) | 0x09);  // 设置FLASH预分频器
PFE0CN = PFE0CN & 0xFE;    // FLASH按字节写入
// 此处读取Loader使能按键
// ...
if (1) { // 用户设置为下载模式
  /** 创建握手过程*/
  Uart_Print("\n");
  Uart_Print("****************ZBoot v1.4.2*****************\n");
  Uart_Print(">Please press 's' to start programming.\n");
  while (1) {
   //  此处判断读入's'
   // ...
   if ("键入正确") {
    RTload();     // Download
   } else if ("超时") {
    goto boot_out;
   }
  }
}
boot_out:
pread = D_RUN_ADDRESS;
if (*pread != 0x02) {
  Uart_Print(">Error: no app program for run!\n");
  while (1);
}
boot = D_RUN_ADDRESS;
(*boot)();
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏1 分享分享 支持支持 反对反对
沙发
发表于 2011-8-16 11:16:39 | 只看该作者
学习了。
板凳
 楼主| 发表于 2011-8-16 11:21:55 | 只看该作者
地板
 楼主| 发表于 2011-8-24 06:21:47 | 只看该作者
大家一起收获
5#
发表于 2013-11-13 22:56:23 | 只看该作者
拿到手了 谢谢啊
6#
发表于 2021-2-13 12:19:57 | 只看该作者
多谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-11-16 03:07 , 耗时 0.164798 秒, 18 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表