打印

STM32使用注意事项

[复制链接]
1272|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mystm32|  楼主 | 2015-2-25 11:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 mystm32 于 2015-3-8 23:51 编辑


本帖最后由 mystm32 于 2015-2-25 11:51 编辑


本帖最后由 mystm32 于 2015-2-25 11:47 编辑


stm32注意事项:1、不同boot选择不同启动位置0处映射地方以及向量表的重映射。2、usart的初始接收标号为1,需要读取后打印否则第一字节乱码。3、isp下载代码用的是bootroader和由它初始化的串口1,因此下载后跳到用户程序时寄存器还是经过了bootroader修改过的值,需要复位后才可恢复默认。4、gpio配置寄存器除了jtak脚为0x8外其他都0x4。5、堆栈双字对齐是由于调用函数时C默认会使用STRD/LDRD入栈,而它们必须要求内存8字节对齐,可设置stkalign来自动检查修改。6、之所以初始化代码要将有复位值的寄存器重复复位,原因还是bootroader有更改过,全体复位则不需。7、注意信号量的副作用,可用互斥指令解决加上DSB等解决缓冲带来的非实时副作用,记住中断任何时候可能发生。8、内联汇编时要注意运行的状态,非特权模式访问特殊功能寄存器将fault,需要注意哪些指令是特权才可以的。

因为汇编指令 *LDRD/STRD指令要求内存单元地址是8字节对齐的。当在程序中使用这些指令 在数据栈中传送数据时,要求数据栈是8字节对齐的。 *连接器要保证要求8字节对齐的数据栈代码只能被数据栈8字节的代码调用。所以对于堆栈8字节对齐的要求,如果纯粹汇编编写程序员可根据指令要求来编写,不对齐可不用该指令即可,然而C编译器默认在调用或中断过程堆栈操作使用,设置STKALIGN可启动自动检查。
记得用DSB来避免缓冲写导致信号量的不准确。

PC值与数据地址区分开来,数据存储地址并不给pc,正常pc也不会指向数据区ra m。
根据boot01设置只是把0位置重映射到0800或1FFF即CODE区的用户代码或bootroader区,其他位置都不存在。因此下载后跳跃至用户区由于系统还是把0当作bootroader,所以跑1FFF找向量而出错。人为设置0也出错。只有设置正确偏移0800才对,因为根据下载时判断已经决定了0对应1FFF。复位后重新判断boot01可解决问题。
计算偏移量与向量偏移寄存器按位或后给PC。伪指令ADR不会设置LSB来符合THUMB而LDR会根据指令数据来设置LSB。
stm32注意事项:
1、复位时对boot0/1引脚的状态检测将决定内存位置0的映射访问区域以及向量表偏移寄存器VTOR为默认值0时所对应的向量表基址位置。
VTOR的复位值为0X0,但是boot1和boot0脚的状态会在复位时进行检测;检测到不同状态执行不同区域的代码,如code区或bootroader区或sram区;同时该状态也决定了VTOR为默认值0x0时所对应的向量表基址位置。即发生中断时到哪个向量表中寻找中断入口地址;所以如果isp下载程序时由于boot1为0和boot0为1,判断后进入bootroader下载用户程序后直接跳转至用户程序而不进行系统复位,则此时默认VTOR=0x0指向的是bootroader首地址处的向量表,并不是code区的向量表,所以采用串口打印时会打印乱码,因为串口中断跳入了不正确的中断子程,除非在中断之前的用户程序中设置VTOR为0x8000000(即设置准确的偏移量而非默认值0x0)后才能正确打印,也就是正确偏移至code区基地址计算向量号。
2、usart的初始接收信号量并未清除,也就是默认为已接收到数据,因此会出现串口打印时第一字母为乱码,可以通过读取USART->SR这一空操作,清除信号量后打印解决该问题。
3、isp下载代码用的是bootroader(芯片厂商固化在flash里的用于isp下载用户程序的代码);执行该程序时会初始化默认串口来接收用户代码,即该段程序已经使用了一些寄存器和改变了它们的上电复位值,因此下载后直接跳到用户程序执行时有些寄存器还是处于bootroader修改过的值,需要复位后才可恢复默认,因此才需要在初始化时钟函数中重新将配置寄存器恢复成默认值。
4、gpio配置寄存器除了jtak调试用脚为0x8配置外其他都0x4。
5、堆栈双字对齐是由于调用函数时C默认会使用STRD/LDRD入栈,而这些指令必须要求内存8字节对齐因此需要堆栈8字节对齐,可设置stkalign位通过硬件来自动检查和修正对齐状态,注意stm32的STKALIGN默认值为0,因此需要用户自己设置。
6、注意信号量的副作用,因为中断产生时间的不确定性,可用互斥指令解决加上DSB等解决缓冲带来的非实时副作用。
7、内联汇编时要注意当前处理器的状态,非特权模式访问特殊功能寄存器将产生fault,需要注意哪些指令是特权才可以使用。
8、伪指令ADR不会设置LSB来符合THUMB而LDR会根据指令数据来设置LSB。
来自iPhone 4S
沙发
搞IT的| | 2015-2-28 18:59 | 只看该作者
复位后重新判断boot01可解决问题。这是怎么解释呀??

使用特权

评论回复
板凳
mystm32|  楼主 | 2015-3-7 10:53 | 只看该作者
搞IT的 发表于 2015-2-28 18:59
复位后重新判断boot01可解决问题。这是怎么解释呀??

//@只有设置NVIC的向量表偏移寄存器才会从BOOTROAD出来后不会打印乱码,
        //但是人为设置成0了就不正常,复位后人为设定为0却正常,复位后不设定也正常但是boot直跳到也不正常,这说明了bootroader后的VTOR还是0,疑惑已经解决,看结论
        ///上述现象可假设为boot10脚的初始读取决定了中断的入口计算,否则只有设置正确的VTOR来矫正/////////////////////////////但是寄存器的值有些还是原来的bootroader处理的垃圾,所以最好复位下。
       
结论是CODE的bootroader还是main code启动位置映射在复位时检测boot脚状态已经确定,如下载程序直接跳main,此时中断向量偏移0代表默认发生中断到bootroader起始位查表,
所以中断会出错,即使main函数中开头将VOTR设置为0也一样,因为0就代表默认的映射值,除非设置准确的偏移量,而不是默认量0,才可。复位后成功是因为复位后已经把0地址与code区
形成映射关系,即使设置成0也行,设置0800即准确值也行。似乎VOTR寄存器与启动映射有着计算关系。
通俗地说,就是在上电复位或其他复位时对boot1和boot0脚的测试就决定了VOTR=0的映射位置,如code区的bootroader区或者0800的用户区,只要复位时确定好了,除非改变向量表时将VOTR改正到确切的位置值,不然的话默认VOTR的0值所代表的就是上次复位的向量表映射位置,比如bootroader区下载完用户程序后跳转到main时,如果产生中断,那么还是跑到bootroader区首地址去定位向量,而不是用户code区0800去找。
stm32的GPIO寄存器复位值并不是全部为0x44444444,jtak和swd引脚复位为“8”,需要关闭该复用功能才可以用于IO输出,即高低跳变。bootroader程序会初始化串口来下载程序,所以直接跳main时很多寄存器是动过的,不是默认复位值,所以初始化函数才会复位相应的值与默认值一致。

使用特权

评论回复
地板
mystm32|  楼主 | 2015-3-10 11:48 | 只看该作者
stm32注意事项:
1、复位时对boot0/1引脚的状态检测将决定内存位置0的映射访问区域以及向量表偏移寄存器VTOR为默认值0时所对应的向量表基址位置。
VTOR的复位值为0X0,但是boot1和boot0脚的状态会在复位时进行检测;检测到不同状态执行不同区域的代码,如code区或bootroader区或sram区;同时该状态也决定了VTOR为默认值0x0时所对应的向量表基址位置。即发生中断时到哪个向量表中寻找中断入口地址;所以如果isp下载程序时由于boot1为0和boot0为1,判断后进入bootroader下载用户程序后直接跳转至用户程序而不进行系统复位,则此时默认VTOR=0x0指向的是bootroader首地址处的向量表,并不是code区的向量表,所以采用串口打印时会打印乱码,因为串口中断跳入了不正确的中断子程,除非在中断之前的用户程序中设置VTOR为0x8000000(即设置准确的偏移量而非默认值0x0)后才能正确打印,也就是正确偏移至code区基地址计算向量号。
2、usart的初始接收信号量并未清除,也就是默认为已接收到数据,因此会出现串口打印时第一字母为乱码,可以通过读取USART->SR这一空操作,清除信号量后打印解决该问题。
3、isp下载代码用的是bootroader(芯片厂商固化在flash里的用于isp下载用户程序的代码);执行该程序时会初始化默认串口来接收用户代码,即该段程序已经使用了一些寄存器和改变了它们的上电复位值,因此下载后直接跳到用户程序执行时有些寄存器还是处于bootroader修改过的值,需要复位后才可恢复默认,因此才需要在初始化时钟函数中重新将配置寄存器恢复成默认值。
4、gpio配置寄存器除了jtak调试用脚为0x8配置外其他都0x4。
5、堆栈双字对齐是由于调用函数时C默认会使用STRD/LDRD入栈,而这些指令必须要求内存8字节对齐因此需要堆栈8字节对齐,可设置stkalign位通过硬件来自动检查和修正对齐状态,注意stm32的STKALIGN默认值为0,因此需要用户自己设置。
6、注意信号量的副作用,因为中断产生时间的不确定性,可用互斥指令解决加上DSB等解决缓冲带来的非实时副作用。
7、内联汇编时要注意当前处理器的状态,非特权模式访问特殊功能寄存器将产生fault,需要注意哪些指令是特权才可以使用。
8、伪指令ADR不会设置LSB来符合THUMB而LDR会根据指令数据来设置LSB。

使用特权

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

本版积分规则

2

主题

4

帖子

0

粉丝