打印
[STM8]

继续针对STM8S的Option byte寻求答案

[复制链接]
20428|54
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yewuyi|  楼主 | 2011-6-23 09:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 yewuyi 于 2011-6-23 10:11 编辑

在ST官方提供的STM8S函数库中,找到了三个函数:

1、uint16_t FLASH_ReadOptionByte(uint16_t Address);
2、void FLASH_ProgramOptionByte(uint16_t Address, uint8_t Data);
3、void FLASH_EraseOptionByte(uint16_t Address);

第一个是读Option byte,第二个对编程Option byte,第三个擦除Option byte,具体函数实现如下:
/**
  * @brief   Programs option byte
  * @param  Address : option byte address to program
  * @param  Data : Value to write
  * @retval None
  */
void FLASH_ProgramOptionByte(uint16_t Address, uint8_t Data)
{
    /* Check parameter */
    assert_param(IS_OPTION_BYTE_ADDRESS_OK(Address));
    /* Enable write access to option bytes */
    FLASH->CR2 |= FLASH_CR2_OPT;
    FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NOPT);
    /* check if the option byte to program is ROP*/
    if (Address == 0x4800)
    {
       /* Program option byte*/
       *((NEAR uint8_t*)Address) = Data;
    }
    else
    {
       /* Program option byte and his complement */
       *((NEAR uint8_t*)Address) = Data;
       *((NEAR uint8_t*)((uint16_t)(Address + 1))) = (uint8_t)(~Data);
    }
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_PROG);
    /* Disable write access to option bytes */
    FLASH->CR2 &= (uint8_t)(~FLASH_CR2_OPT);
    FLASH->NCR2 |= FLASH_NCR2_NOPT;
}
/**
  * @brief   Erases option byte
  * @param  Address : Option byte address to erase
  * @retval None
  */
void FLASH_EraseOptionByte(uint16_t Address)
{
    /* Check parameter */
    assert_param(IS_OPTION_BYTE_ADDRESS_OK(Address));
    /* Enable write access to option bytes */
    FLASH->CR2 |= FLASH_CR2_OPT;
    FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NOPT);
     /* check if the option byte to erase is ROP */
     if (Address == 0x4800)
    {
       /* Erase option byte */
       *((NEAR uint8_t*)Address) = FLASH_CLEAR_BYTE;
    }
    else
    {
       /* Erase option byte and his complement */
       *((NEAR uint8_t*)Address) = FLASH_CLEAR_BYTE;
       *((NEAR uint8_t*)((uint16_t)(Address + (uint16_t)1 ))) = FLASH_SET_BYTE;
    }
    FLASH_WaitForLastOperation(FLASH_MEMTYPE_PROG);
    /* Disable write access to option bytes */
    FLASH->CR2 &= (uint8_t)(~FLASH_CR2_OPT);
    FLASH->NCR2 |= FLASH_NCR2_NOPT;
}
/**
  * @brief   Reads one option byte
  * @param  Address  option byte address to read.
  * @retval Option byte read value + its complement
  */
uint16_t FLASH_ReadOptionByte(uint16_t Address)
{
    uint8_t value_optbyte, value_optbyte_complement = 0;
    uint16_t res_value = 0;
    /* Check parameter */
    assert_param(IS_OPTION_BYTE_ADDRESS_OK(Address));

    value_optbyte = *((NEAR uint8_t*)Address); /* Read option byte */
    value_optbyte_complement = *(((NEAR uint8_t*)Address) + 1); /* Read option byte complement */
    /* Read-out protection option byte */
    if (Address == 0x4800)  
    {
        res_value =  value_optbyte;
    }
    else
    {
        if (value_optbyte == (uint8_t)(~value_optbyte_complement))
        {
            res_value = (uint16_t)((uint16_t)value_optbyte << 8);
            res_value = res_value | (uint16_t)value_optbyte_complement;
        }
        else
        {
            res_value = FLASH_OPTIONBYTE_ERROR;
        }
    }
    return(res_value);
}
这些库函数做的非常棒,这说明编译器完全可以在源代码中将选项字节部分的数据编译到烧写芯片的HEX中,但STVD+COSMIC为何单单不给出这个方法,而只给出了在程序代码中通过程序来操作FLASH的方式的写入选项字节。

我实在想不懂STVD+COSMIC如此这般的原因,如果用户根本就不需要在程序烧写后调整选项字节,但按照现在这种方法,依然需要写一大段代码,这岂不是白白浪费代码空间和工程师精力?而且在源代码中加入了这么一段操作选项字节的代码,那么从概率上讲,当MCU的PC指针异常后,完全可能出现非法操作选项字节的可能,这岂不是工程师给自己找麻烦,肯定是吃力不讨好嘛。

总体来说,一个产品设计完毕后,99.999%的用户不太可能再去修改选项字节,STVD+COSMIC为何霍视这绝大多数用户的要求,强烈呼吁ST和COSMIC增加直接在源代码中对选项字节的赋值操作,当然,目前的这三个库函数也应该继续保留,这样也可以满足一些特殊用户的需求。
沙发
Simon21ic| | 2011-6-23 10:02 | 只看该作者
下面呢?

使用特权

评论回复
板凳
香水城| | 2011-6-23 10:03 | 只看该作者
什么问题?

使用特权

评论回复
地板
yewuyi|  楼主 | 2011-6-23 10:09 | 只看该作者
这些库函数做的非常棒,这说明编译器完全可以在源代码中将选项字节部分的数据编译到烧写芯片的HEX中,但STVD+COSMIC为何单单不给出这个方法,而只给出了在程序代码中通过程序来操作FLASH的方式的写入选项字节。

我实在想不懂STVD+COSMIC如此这般的原因,如果用户根本就不需要在程序烧写后调整选项字节,但按照现在这种方法,依然需要写一大段代码,这岂不是白白浪费代码空间和工程师精力?而且在源代码中加入了这么一段操作选项字节的代码,那么从概率上讲,当MCU的PC指针异常后,完全可能出现非法操作选项字节的可能,这岂不是工程师给自己找麻烦,肯定是吃力不讨好嘛。

总体来说,一个产品设计完毕后,99.999%的用户不太可能再去修改选项字节,STVD+COSMIC为何霍视这绝大多数用户的要求,强烈呼吁ST和COSMIC增加直接在源代码中对选项字节的赋值操作,当然,目前的这三个库函数也应该继续保留,这样也可以满足一些特殊用户的需求。

使用特权

评论回复
5
yewuyi|  楼主 | 2011-6-23 10:10 | 只看该作者
上面两位速度太快,俺还没来得及写完呢,怕帖子太长,先发了一部分,我这就把问题补到首帖后面。

使用特权

评论回复
6
xwj| | 2011-6-23 10:22 | 只看该作者
;P

使用特权

评论回复
7
yewuyi|  楼主 | 2011-6-23 10:30 | 只看该作者
;P
xwj 发表于 2011-6-23 10:22



洗碗机不准偷笑,抓紧帮我想办法。:@

使用特权

评论回复
8
mcuisp| | 2011-6-23 11:23 | 只看该作者
一个变通的方法:指定某一个FLASH EEPROM区域存储OptionBytes,编程器把这个区域的内容写入OPTIONBytes。
比如指定EEPROM的一个区域。

使用特权

评论回复
9
yewuyi|  楼主 | 2011-6-23 11:28 | 只看该作者
一个变通的方法:指定某一个FLASH EEPROM区域存储OptionBytes,编程器把这个区域的内容写入OPTIONBytes。
比如指定EEPROM的一个区域。
mcuisp 发表于 2011-6-23 11:23


那这可就完全依靠编程器软件支持了,对于ST和COSMIC自身来说,这样做还不如直接给出在源代码中生成option byte的HEX来的简洁吧。

使用特权

评论回复
10
IJK| | 2011-6-23 12:29 | 只看该作者
其实,通过ST的 STVP 软件,直接可以修改 option bytes;当然,STVP 也可以把option bytes保存到.hex/.s19文件,以及从.hex/.s19文件load option bytes

使用特权

评论回复
11
mcuisp| | 2011-6-23 12:36 | 只看该作者
叶兄,我研究出来办法,你买我手持机么?:lol

使用特权

评论回复
12
yewuyi|  楼主 | 2011-6-23 13:25 | 只看该作者
其实,通过ST的 STVP 软件,直接可以修改 option bytes;当然,STVP 也可以把option bytes保存到.hex/.s19文件,以及从.hex/.s19文件load option bytes
IJK 发表于 2011-6-23 12:29


这个不是我想要的,这种方式的弊端显而易见。

使用特权

评论回复
13
yewuyi|  楼主 | 2011-6-23 13:29 | 只看该作者
叶兄,我研究出来办法,你买我手持机么?:lol
mcuisp 发表于 2011-6-23 12:36


不能保证。
我们的编程器现在都是代理商送的原厂推荐使用的编程器,如果原厂推荐使用你的产品的话,那么我们可以指定代理商送你那个型号,否则有点小麻烦。

使用特权

评论回复
14
mcuisp| | 2011-6-23 13:33 | 只看该作者
初步研究结果----
源代码里面:
const unsigned char OptROP=0xa5;
const unsigned char OptOPT1=0xaa;
const unsigned char OptNOPT1=0x55;
const unsigned char OptOPT2=0x66;
const unsigned char OptNOPT2=0x99;
输出的hex片段:
:15480000A5AA5566990000000000000000000000000000000000

使用特权

评论回复
15
yewuyi|  楼主 | 2011-6-23 14:19 | 只看该作者
初步研究结果----
源代码里面:
const unsigned char OptROP=0xa5;
const unsigned char OptOPT1=0xaa;
const unsigned char OptNOPT1=0x55;
const unsigned char OptOPT2=0x66;
const unsigned char OptNOPT2=0x99; ...
mcuisp 发表于 2011-6-23 13:33


晕倒,头文件里面定义OptROP了吗?

呵呵,我马上看看头文件去。

使用特权

评论回复
16
mcuisp| | 2011-6-23 14:20 | 只看该作者
本帖最后由 mcuisp 于 2011-6-23 14:23 编辑

头文件里没有啦,这个我自己写的。
const unsigned char OptArray[]=
  {
0xa5,//ROP
0xaa,0x55,//OPT1
0x66,0x99,//OPT2
0x00,0xff,//opt3
0x01,0xfe,//opt4
0x02,0xfd,//OPT5
0x03,0xfc,//OPT6
0x04,0xfb,//OPT7
0x05,0xfa,//OPT8
0x06,0xf9,//OPT9
0x07,0xf8,//OPT10
  };
==》
:15480000A5AA55669900FF01FE02FD03FC04FB05FA06F907F808
编译工具COSMIC+STVD

使用特权

评论回复
17
yewuyi|  楼主 | 2011-6-23 14:23 | 只看该作者
初步研究结果----
源代码里面:
const unsigned char OptROP=0xa5;
const unsigned char OptOPT1=0xaa;
const unsigned char OptNOPT1=0x55;
const unsigned char OptOPT2=0x66;
const unsigned char OptNOPT2=0x99; ...
mcuisp 发表于 2011-6-23 13:33


经查,头文件里面没有定义OptROP等,该源代码也没有进行绝对定位,所以,到底是怎么指向0X4800等地址的呢?

使用特权

评论回复
18
mcuisp| | 2011-6-23 14:29 | 只看该作者
我得把手持机上位机升级下,下回有客户需要,就可以提供这个技术支持了,呵呵。
FLASH+EEPROM+OPTIONBYTES,统统集成进去。

使用特权

评论回复
19
yewuyi|  楼主 | 2011-6-23 14:37 | 只看该作者
我得把手持机上位机升级下,下回有客户需要,就可以提供这个技术支持了,呵呵。
FLASH+EEPROM+OPTIONBYTES,统统集成进去。
mcuisp 发表于 2011-6-23 14:29


如何实现定位到0x4800的开始地址?

使用特权

评论回复
20
mcuisp| | 2011-6-23 14:43 | 只看该作者
;P过程有些复杂,不完美,COSMIC还是不尽人意,呵呵。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:一:我的回帖多数只是猜测/估计/想象,建立在我现有知识结构的理解和分析上,多数都没有动手实际检验过,请斟酌采纳. 二:若对我的技术类主帖或回帖有异议,欢迎讨论,拒绝过激攻击或辱骂,否则全站追杀屏蔽发帖,后果自负. 三:对本人的其它意见,请直接向站长投诉,勿使用站内短信骚扰/挑衅/辱骂,否则将全站追杀屏蔽发帖,后果自负.

1416

主题

20007

帖子

232

粉丝