Tag: cortex m

C中的双重函数间接

我正在为ARM Cortex-M0 CPU编写一个bootloader。 我需要将IRQ转发到目标应用程序,遗憾的是,此CPU中的IRQ向量位于固定地址,我无法重新定位,所以我需要一些技巧。 我知道目标应用程序的IRQ的地址存储的地址。 所以,假设在地址0x5008处有void x_IRQHandler(void)的地址(目标app) 我想做的是: 在启动时保存所有x_IRQHandler()的地址(以便它不在运行时计算); 每当引导加载程序收到IRQ调用时,从其地址调用目标应用程序中的相关IRQ函数。 这是我在bootloader中所做的,我找不到合适的语法。 //pointers to x_IRQHandler() functions void(* x_IRQ_addr)(void); x_IRQ_addr = (void(*)(void))(0x5008); //here I should call the function pointed by x_IRQ_addr; but this syntax is not valid void x_IRQ_Handler(void) { *x_IRQ_addr(); } 我尝试了不同的方法但没有成功,我该如何解决?

16位int机器(MSP430)和32位int机器(ARM CORTEX)的减法结果不同

当下面的代码针对像MSP430微控制器这样的16位整数机器运行时, s32产生65446。 #include uint16_t u16c; int32_t s32; int main() { u16c = 100U; s32 = 10 – u16c; } 我的理解是10-u16c将隐式类型提升为unsigned int。 数学上10-u16c等于-90。 但是如何将负数表示为unsigned int呢? 当-90被提升为unsigned int时,是否意味着忽略了数字的符号? 让我们假设,数字的符号被忽略。 90的二进制表示是00000000 01011010 。 当这被分配给32位宽的有符号整数变量s32 ,转换是如何发生的? 为了使s32等于65446,90必须采用2的补码。 那将是00000000 10100110 。 我不太了解s32成为65446的过程。 在像ARM这样的32位宽整数机器中, s32是-90,这是正确的。 要在16位整数机器中修复这种情况, (int16_t)需要(int16_t)的类型转换。 这如何解决这个问题? 添加了s32六进制数据表示,如IAR Workbench(右下角)所示。 结果表明s32变为0x0000FFA6 。 因此对于MSP430,从无符号16位转换为有符号32位的机器实现,它只是预先设置16 0位。

在ARM Cortex-M3上编写一个简单的C任意代码执行漏洞?

我正在尝试用C语言编写一个概念certificate,它演示了ARM Cortex-M3上堆栈中内存缓冲区的代码执行。 这将有助于certificate正确使用ARM MPU可以防止此类攻击。 我想一个快速而肮脏的方法来将一些代码放入堆栈中是从常规函数中复制它然后使用goto跳转到它,如下所示: static void loopit(void) { printf(“loopit\n”); while (1); } void attack(void) { uint8_t buffer[64] __attribute__((aligned(4))); memcpy(buffer, loopit, sizeof(buffer)); goto *((void *) (int) buffer); } 我希望当我调用攻击函数时,它会将代码复制到堆栈中,跳转到它,打印消息并进入无限循环。 但是,我在故障寄存器中得到以下值的exception: HFSR = 0x40000000 CFSR = 0x00020000 PSR = 0x60000000 这似乎是UFSR中的INVSTATE位,表示“非法使用EPSR”,我读到的通常是由于BX指令试图跳转到LSB设置为0的地址,处理器将其解释为函数其中包含非Thumb代码,但Cortex-M处理器仅允许Thumb代码。 我看到memcpy被赋予了loopit函数的奇数地址,因为我假设编译器正在将实际内存地址与1或运算。 所以我认为修复就像重写我的攻击函数一样: void attack(void) { uint8_t buffer[64] __attribute__((aligned(4))); memcpy(buffer, ((int) loopit) & ~1, sizeof(buffer)); goto […]

每个周期的ARM M4指令(IPC)计数器

我想计算在ARM cortex-M4(或cortex-M3)处理器上执行的每个周期的指令数。 它需要的是:我想要分析的代码的指令数量 (在运行时执行)以及代码执行的周期数 。 1 – 周期数 使用循环计数器非常简单直接。 volatile unsigned int *DWT_CYCCNT ; volatile unsigned int *DWT_CONTROL ; volatile unsigned int *SCB_DEMCR ; void reset_timer(){ DWT_CYCCNT = (int *)0xE0001004; //address of the register DWT_CONTROL = (int *)0xE0001000; //address of the register SCB_DEMCR = (int *)0xE000EDFC; //address of the register *SCB_DEMCR = *SCB_DEMCR | 0x01000000; […]

在core_cm4.h上为什么会像((uint32_t)(int32_t)IRQn那样)?

在core_cm4.h的以下代码中,为什么会有双重转换((uint32_t)(int32_t)IRQn) ? 例如,在以下function中: __STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) { NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); } 这样做的目的是什么?

Cortex M3的Bootloader

我正在使用mbed的LPC 1768板(带有cortex M3 cpu),我正在尝试在这里实现一些function,主要是从SD卡升级用户应用程序,我正在编写两个程序,首先是一个bootloader / nano-kernel,以及一个用户应用程序(helloworld将开始): 在0x00地址运行的Bootloader / nano-kernel,它会做一些检查并最终获取SD卡上的二进制文件 Bootloader / nano-kernel会将这个二进制文件复制到地址0x9000(以后可能需要更改,但bootloader / nano-kernel不会使用此空间,所以应该没问题) Bootloader跳转到0x9000 + 4的用户应用程序 Sd卡很容易解决,我遇到了跳跃部分的问题。 这是跳跃函数的代码。 void run(void) { void (*user_code_entry)(void); unsigned *p; SCB->VTOR = (USER_FLASH_START & 0x1FFFFF80); // Load contents of second word of user flash – the reset handler address // in the applications vector table p = (unsigned *)(USER_FLASH_START […]

未对齐访问会导致ARM Cortex-M4出错

我有一个对象,其地址不是4字节对齐的。 当存在STR指令保存2个寄存器时,这会在cpu中导致HardFault错误。 这是生成的代码: 00000000 : 0: b510 push {r4, lr} 2: 4604 mov r4, r0 4: 6042 str r2, [r0, #4] 6: e9c4 3102 strd r3, r1, [r4, #8] a: 2001 movs r0, #1 c: 7420 strb r0, [r4, #16] e: b921 cbnz r1, 1a 这些是“4:6042 ……”行的寄存器 R0 08738B82 R8 0 R1 08738BAE R9 0 […]