OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2324|回复: 13

C语言的字节型指针转换为字型指针导致死机

[复制链接]

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
发表于 2019-3-4 15:24:19 | 显示全部楼层 |阅读模式
10金钱
本帖最后由 ZDawn 于 2019-3-4 15:48 编辑

测试代码如下:
uint8_t a[8] = {0};
int main(void)
{
    uint32_t temp;
    uint32_t *p = (uint32_t *)&a[0];


    temp = *p;    //运行此句会硬件跑飞
    while(1);
}


这种情况会是什么原因呢?

最佳答案

查看完整内容[请看2#楼]

破案了!!! 字节型指针转换为字型指针的时候,字节型指针所指向的地址必须是4的倍数才不会死机。也就是说 数组a的地址必须是4的倍数
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
 楼主| 发表于 2019-3-4 15:24:20 | 显示全部楼层
破案了!!!
字节型指针转换为字型指针的时候,字节型指针所指向的地址必须是4的倍数才不会死机。也就是说 数组a的地址必须是4的倍数
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7573
金钱
7573
注册时间
2016-11-30
在线时间
643 小时
发表于 2019-3-4 15:28:39 | 显示全部楼层
如何确定程序跑飞了?
回复

使用道具 举报

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
 楼主| 发表于 2019-3-4 15:29:52 | 显示全部楼层
lvkanger 发表于 2019-3-4 15:28
如何确定程序跑飞了?

对,单步调试的时候发现程序跑到 HardFault_Handler()中断那里去了
回复

使用道具 举报

9

主题

796

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2038
金钱
2038
注册时间
2017-8-2
在线时间
522 小时
发表于 2019-3-4 15:33:28 | 显示全部楼层
uint32_t *p = (uint32_t *)&a[0];   改一改这句
猪猪熊呢?
回复

使用道具 举报

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
 楼主| 发表于 2019-3-4 15:34:41 | 显示全部楼层
我在STM32F103RC上运行这段测试代码没问题,但是到了GD32上面运行就死机了
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7573
金钱
7573
注册时间
2016-11-30
在线时间
643 小时
发表于 2019-3-4 15:37:52 | 显示全部楼层
ZDawn 发表于 2019-3-4 15:29
对,单步调试的时候发现程序跑到 HardFault_Handler()中断那里去了

我测试了,不跑飞啊,代码正常
回复

使用道具 举报

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
 楼主| 发表于 2019-3-4 15:41:07 | 显示全部楼层
323232 发表于 2019-3-4 15:33
uint32_t *p = (uint32_t *)&a[0];   改一改这句

我试过把这句改为
uint32_t *p = (uint32_t *)a;
也会死机
回复

使用道具 举报

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
 楼主| 发表于 2019-3-4 15:42:00 | 显示全部楼层
lvkanger 发表于 2019-3-4 15:37
我测试了,不跑飞啊,代码正常

我在STM32上测试也没问题,但是GD32就会死机。不知道是不是GD32的问题。。。还是编译器
回复

使用道具 举报

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
 楼主| 发表于 2019-3-4 15:52:52 | 显示全部楼层
本帖最后由 ZDawn 于 2019-3-4 15:55 编辑

代码改为这样就不会死机,字节型转换为半字型

uint8_t a[8] = {0};
int main(void)
{
    uint16_t temp;
    uint16_t *p = (uint16_t *)&a[0];


    temp = *p;   
    while(1);
}
但MCU是32bit的
回复

使用道具 举报

23

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
244
金钱
244
注册时间
2011-12-29
在线时间
1 小时
发表于 2019-3-5 11:31:20 | 显示全部楼层
查一下字节对其的相关资料就好了
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-3-5 11:52:15 | 显示全部楼层
如果说字节数组是需要你类型转换, 就应该在定义数组前加#pragma pack (4)对齐
回复

使用道具 举报

28

主题

150

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
488
金钱
488
注册时间
2016-9-29
在线时间
113 小时
 楼主| 发表于 2019-3-5 12:05:37 | 显示全部楼层
edmund1234 发表于 2019-3-5 11:52
如果说字节数组是需要你类型转换, 就应该在定义数组前加#pragma pack (4)对齐

是GD32的问题,在ST上使用字类型指针指向一个 不是4倍数的地址时候(比如0x07),MCU是会分两次存取完成的。在GD32上这么用就会死机
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-3-5 14:28:27 | 显示全部楼层
本帖最后由 edmund1234 于 2019-3-5 14:49 编辑
ZDawn 发表于 2019-3-5 12:05
是GD32的问题,在ST上使用字类型指针指向一个 不是4倍数的地址时候(比如0x07),MCU是会分两次存取完成的 ...

uint32_t *p = (uint32_t *)&a[0];   -----(1
uint16_t *p = (uint16_t *)&a[0];  -------(2

a 在1)的情况下要4字节对齐, 在2)的情况下要2字节对齐
这跟ST或GD 无关

只要你把a放在地址最后一位是7, temp = *p; 就会触发HardFault_Handler异常, 不管是ST还是GD

如果说ST没事, 那你查看一下a这时的地址吧, 看它还是不是尾数是7

不要把美丽的误会当成经验

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-24 00:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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