单片机0xFFFFFFFE死机问题解决

问题描述

最近在忙公司项目的时候,要调试一个新功能,防止BootLoader的干扰,故将BootLoader屏蔽了,直接将app的中断向量表改为默认的,发现运行不了,将所有代码屏蔽掉,只留一个系统滴答定时器,和一个gpio控制灯光闪烁。发现还是运行不了。卡死在如下界面:
在这里插入图片描述
0xFFFFFFFE 0000 MOVS r0,r0 卡死在了这一句汇编代码。很明显这个地址已经超出了mcu内存的寻址范围。经过多次测试都是这个问题。

问题排查

反复编译验证后,发现如果将delay函数改为硬件延时同时屏蔽掉系统滴答定时器的初始化,就是工作正常。上图中的delay是调用了系统滴答定时器的计数值。

疑似跟系统定时器有关系,最终发现滴答定时器的中断怎么都进不了。换另外一块板子上的程序也改成只有一个闪灯和系统滴答定时器,然而在另外一块板子上的程序能正常运行。与硬件同事排查了晶振是否起振,都正常。

百度这个问题,也没有发现如何解决,基本分析都是指针指向了内存以外的地址,可能是野指针问题,但是,明显跟我这情况不同,我这代码不可能存在野指针(都没有用到指针)。

问题解决

排查了一圈后,发现领一块板子上的程序运行正常,且这两块板子的单片机型号是一样的,不同的是两块板子的晶振频率不一样。仅此区别,最后还是怀疑代码中哪里有问题。于是从.s文件开始查找。
在这里插入图片描述
单片机上电后先是调用了SystemInit函数,该函数执行完毕后,才跳转到main函数执行。找到该函数的定义。

void SystemInit(void)
{
    /* FPU settings */
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 20) | (3UL << 22)); /* set CP10 and CP11 Full Access */
#endif
    SystemCoreClockUpdate();
#if defined (ROM_EXT_QSPI)
    SystemInit_QspiMem();
#endif /* ROM_EXT_QSPI */
    /* Configure the Vector Table relocation */
    SCB->VTOR = VECT_TAB_OFFSET;    /* Vector Table Relocation */
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/9fd1acb8d76046cdb86897e58ac94dee.png
这个函数的最后一句指定了中断向量表的地址。一般来说都是单片机运行的起始地址,对于stm32 或gd32等中断向量表默认是0x8000000,对于hc32是0x0。接着看下VECT_TAB_OFFSET发现该值不是默认值,而被改到了app的中断向量表位置。到这里虎躯一震,感觉问题找到了,立刻将改宏定义改为0x0,编译运行,一切正常,led灯按照2s的周期稳定闪烁。至此问题解决!

吐槽:感谢前同事写的一手好代码。正常使用了bootloader后都是在main函数中,改变中断向量表的位置。而SystemInit这是系统起来前的硬件初始化,基本上不会去动它。很难想象前同事为什么要改这里。

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
// ake32.c #include "ake32.h" // performs n ^ 2 mod p operation word32 squaremod( word32 n, word32 p ) { word32 k, sum, result = 0; word32 partial; int carry = 0; // copy 'n' into 'sum' and into 'bits' and set 'n' to zero k = sum = n; // extract the bits from the right part of 'bits' // for each bit to 1 we add 'sum' to 'n' // 'sum' is shifted to the left in each step while ( k > 0 ) { if ( k & 1 ) { // if bit0 == 1 // then we add 'sum' to 'result' partial = result + sum; if ( (partial < result) || (partial < sum) ) carry = 1; result = partial; // check if 'result' is greater than 'p' if ( (result > p) || carry ) {// if result>p then result-p */ result -= p; carry = 0; } } // Multiply sum by 2 if ( sum & 0x80000000 ) carry = 1; sum <<= 1; // check if sum is greater than 'p' if ( (sum > p) || carry ) { // if sum>p then sum-p sum -= p; carry = 0; } k >>= 1; } return result; } // performs the leftwise rotation operation on a 128-bit word void rotl128( word32 * a, int b ) { word32 temp1, temp2; register int i; if ( b < 32 ) { temp1 = a[3]; for ( i = 3; i > 0; i-- ) { a[i] <<= b; if ( b != 0 ) a[i] |= a[i-1] >> (32-b); } a[0] <<= b; if ( b != 0 ) a[0] |= temp1 >> (32-b); } else if ( b < 64 ) { temp1 = a[3]; temp2 = a[2]; for ( i = 3; i > 1; i-- ) { a[i] = 0; a[i] = a[i-1] << (b-32); if ( b != 32 ) a[i] |= a[i-2] >> (64-b); } a[1] = 0; a[1] = a[0] << (b-32); if ( b != 32 ) a[1] |= temp1 >> (64-b); a[0] = 0; a[0] = temp1 << (b-32); if ( b != 32 ) a[0] |= temp2 >> (64-b); } else if ( b < 96 ) { temp1 = a[0]; temp2 = a[1]; b = 128-b; for ( i = 0; i < 2; i++ ) { a[i] = 0; if ( b != 64 ) a[i] = a[i+1] >> (b-32); a[i] |= a[i+2] << (64-b); } a[2] = 0; if ( b != 64 ) a[2] = a[3] >> (b-32); a[2] |= temp1 << (64-b); a[3] = 0; if ( b != 64 ) a[3] = temp1 >> (b-32); a[3] |= temp2 << (64-b); } else { temp1 = a[0]; b = 128-b; for ( i = 0; i < 3; i++ ) { if ( b != 32 ) a[i] >>= b; else a[i] = 0; a[i] |= a[i+1] << (32-b); } if ( b != 32 ) a[3] >>= b; else a[3] = 0; a[3] |= temp1 << (32-b); } } // rotate left the 31 most significant bits word32 rotl31( word32 x, int y ) { word32 bit = 0; bit = x & 0x1; x &= 0xfffffffe; return ((x<<(y&0x1f)) | (x>>(31-(y&0x1f))))|bit; } // rotate left the 31 less significant bits word32 rotl1( word32 x, int y ) { word32 bit = 0; bit = x & 0x80000000; x &= 0x7fffffff; return ((x<<(y&0x1f)) | (x>>(31-(y&0x1f))))|bit; } // generate the encryption subkeys from the user-key void en_key_ake32(word32 *userkey, word32 *EK) { register int i; word32 t[DWORDS_IN_KEY]; // First we initialize the auxiliar variables t(i) // t(i) = (k(i)+a(i))^2 mod p(i) for ( i = 0; i < DWORDS_IN_KEY; i++ ) t[i] = squaremod( userkey[i]+constant[i], prime[i] ); // Next we calculate as many subkeys as necessary for ( i = 0; i < SUBKEYS; i++ ) { // K(i) = t(i) ^ t(i+2) EK[i] = t[i%DWORDS_IN_KEY] ^ t[(i+2)%DWORDS_IN_KEY]; // t(i) = (t(i) ^ t(i+1)) mod p(i) t[i%DWORDS_IN_KEY] = squaremod( t[i%DWORDS_IN_KEY]^t[(i+1)%DWORDS_IN_KEY], prime[i%DWORDS_IN_KEY] ); // t(i+2) = (t(i+2) ^ t(i+3)) mod p(i+2) t[(i+2)%DWORDS_IN_KEY] = squaremod( t[(i+2)%DWORDS_IN_KEY]^t[(i+3)%DWORDS_IN_KEY], prime[(i+2)%DWORDS_IN_KEY] ); } } // generates the decryption subkeys from the encryption subkeys void de_key_ake32(ake32key EK, ake32key DK) { register int i, j; word32 t1, t2, t3, t[11]; ake32key T; word32 *p=T+SUBKEYS; t1=-*EK++; t2=*EK++; t3=*EK++; *--p=-*EK++; *--p=t3; *--p=t2; *--p=t1; *--p=128-(*EK++)&0x7f; for (j=0;j<ROUNDS;j++) { for ( i = 0; i < 11; i++ ) t[i]=*EK++; *--p=*EK++; for ( i = 10; i >= 0; i-- ) *--p=t[i]; *--p=128-(*EK++)&0x7f; } t1=-*EK++; t2=*EK++; t3=*EK++; *--p=-*EK++; *--p=t3; *--p=t2; *--p=t1; //copy and destroy temp copy for(j=0,p=T;j<SUBKEYS;j++) { *DK++=*p; *p++=0; } } // encrypts the input text into the output ciphertext using the subkeys void cipher_ake32( word32 in[4], word32 out[4], register ake32key EK ) { word32 x[4], t1, t2; int r = ROUNDS; x[0] = *in++; x[1] = *in++; x[2] = *in++; x[3] = *in; // Initial rotation and addition and XOR operations x[0] += *EK++; x[1] ^= *EK++; x[2] ^= *EK++; x[3] += *EK++; do { rotl128( x, (*EK++)&0x7f ); t1 = x[0] ^ x[2]; t2 = x[1] ^ x[3]; // Next, the additions-rotations t2 = rotl31( t2, t1 ); t2 += *EK++; t2 = rotl1( t2, t1 >> 5 ); t2 += *EK++; t2 = rotl31( t2, t1 >> 10 ); t2 += *EK++; t2 = rotl1( t2, t1 >> 15 ); t2 += *EK++; t2 = rotl31( t2, (t1 >> 20)&0xf ); t2 += *EK++; t2 = rotl1( t2, (t1 >> 24)&0xf ); t2 += *EK++; t2 = rotl31( t2, (t1 >> 28)&0xf ); t1 = rotl1( t1, t2 ); t1 += *EK++; t1 = rotl31( t1, t2 >> 5 ); t1 += *EK++; t1 = rotl1( t1, t2 >> 10 ); t1 += *EK++; t1 = rotl31( t1, t2 >> 15 ); t1 += *EK++; t1 = rotl1( t1, (t2 >> 20)&0xf ); t1 += *EK++; t1 = rotl31( t1, (t2 >> 24)&0xf ); t1 += *EK++; t1 = rotl1( t1, (t2 >> 28)&0xf ); x[0] ^= t2; x[2] ^= t2; x[1] ^= t1; x[3] ^= t1; } while (--r); // Final rotation and addition and XOR operations rotl128( x, (*EK++)&0x7f ); *out++ = x[0] + *EK++; *out++ = x[1] ^ *EK++; *out++ = x[2] ^ *EK++; *out = x[3] + *EK; } int main ( ) { word32 userkey[DWORDS_IN_KEY] = { 0x0000000,0x0000,0x0000,0X0000 }; clock_t start, finish; word32 AA[4],BB[4],CC[4]; ake32key EK,DK; register long l; FILE *fich; AA[0] = AA[1] = AA[2] = 0; AA[3] = 0x10000000; en_key_ake32(userkey,EK); fich = fopen( "clave3.txt", "wt" ); for ( l = 0; l < SUBKEYS; l++ ) fprintf( fich, "EK[%d] = %08X\n", l, EK[l] ); de_key_ake32(EK,DK); fclose( fich ); printf( "AA = %08X %08X %08X %08X\n", AA[0], AA[1], AA[2], AA[3] ); printf("\nEncrypting %lu words: ", ITERATIONS ); start = clock( ); cipher_ake32(AA,BB,EK); /*for ( l = 0; l < ITERATIONS; l++ ) cipher_ake32(BB, BB, EK);*/ finish = clock( ) - start; fich = fopen( "crypt.txt", "at" ); fprintf( fich, "BB = %08X %08X %08X %08X\n", BB[0], BB[1], BB[2], BB[3] ); fclose( fich ); printf( "BB = %08X %08X %08X %08X\n", BB[0], BB[1], BB[2], BB[3] ); printf( "%2.3f seconds\n", (double) finish/CLK_TCK ); printf("\nDecrypting %lu words: ", ITERATIONS ); start = clock( ); cipher_ake32( BB, CC, DK ); /*for ( l = 0; l < ITERATIONS; l++ ) cipher_ake32( CC, CC, DK );*/ finish = clock( ) - start; printf( "CC = %08X %08X %08X %08X\n", CC[0], CC[1], CC[2], CC[3] ); printf( "%2.3f seconds\n", (double) finish/CLK_TCK ); getchar( ); return 0; }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值