diff --git a/bsp/at91sam9260/rtconfig.h b/bsp/at91sam9260/rtconfig.h index 1fe71580b8f325af7615fc34892dbdfabcf03776..1080c981732acb8edc296886f2674f6d2ba3b808 100755 --- a/bsp/at91sam9260/rtconfig.h +++ b/bsp/at91sam9260/rtconfig.h @@ -22,6 +22,8 @@ #define RT_USING_OVERFLOW_CHECK +#define RT_USING_INTERRUPT_INFO + /* Using Hook */ #define RT_USING_HOOK diff --git a/include/rthw.h b/include/rthw.h index 817b9f40f2a44436149449a0d17508fa82186891..d92b5e85909fd538aee0a8bec7b060f47537b7fc 100644 --- a/include/rthw.h +++ b/include/rthw.h @@ -24,6 +24,9 @@ extern "C" { #endif +/* + * CPU interfaces + */ void rt_hw_cpu_icache_enable(void); void rt_hw_cpu_icache_disable(void); rt_base_t rt_hw_cpu_icache_status(void); @@ -38,6 +41,24 @@ rt_uint8_t *rt_hw_stack_init(void *entry, rt_uint8_t *stack_addr, void *exit); +/* + * Interrupt handler definition + */ +typedef void (*rt_isr_handler_t)(int vector, void *param); + +struct rt_irq_desc { + rt_isr_handler_t handler; + void *param; + +#ifdef RT_USING_INTERRUPT_INFO + char name[RT_NAME_MAX]; + rt_uint32_t counter; +#endif +}; + +/* + * Interrupt interfaces + */ void rt_hw_interrupt_init(void); void rt_hw_interrupt_mask(int vector); void rt_hw_interrupt_umask(int vector); @@ -45,10 +66,13 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, char *name); -void rt_hw_interrupt_handle(int vector); rt_base_t rt_hw_interrupt_disable(void); void rt_hw_interrupt_enable(rt_base_t level); + +/* + * Context interfaces + */ void rt_hw_context_switch(rt_uint32_t from, rt_uint32_t to); void rt_hw_context_switch_to(rt_uint32_t to); void rt_hw_context_switch_interrupt(rt_uint32_t from, rt_uint32_t to); @@ -59,7 +83,7 @@ void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry); void rt_hw_show_memory(rt_uint32_t addr, rt_uint32_t size); /* - * exception interfaces + * Exception interfaces */ void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context)); diff --git a/include/rtthread.h b/include/rtthread.h index dbe48b492e710a8ce8e58f9e35ab385b6502981a..be43f36ec90fe1849a299010abe28dc52b07589f 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -425,15 +425,6 @@ void rt_module_unload_sethook(void (*hook)(rt_module_t module)); /* * interrupt service */ -typedef void (*rt_isr_handler_t)(int vector, void *param); - -struct rt_irq_desc { - char irq_name[RT_NAME_MAX]; - rt_isr_handler_t isr_handle; - void *param; - rt_uint32_t interrupt_cnt; -}; - /* * rt_interrupt_enter and rt_interrupt_leave only can be called by BSP diff --git a/libcpu/arm/at91sam926x/interrupt.c b/libcpu/arm/at91sam926x/interrupt.c index 012ecc66aaac42fdf6dcddc601d4ef589cd0c1a1..91aaba14183dcbd8def52e6169f21166f5299374 100755 --- a/libcpu/arm/at91sam926x/interrupt.c +++ b/libcpu/arm/at91sam926x/interrupt.c @@ -12,10 +12,10 @@ * 2011-01-13 weety first version */ -#include +#include #include "at91sam926x.h" -#define MAX_HANDLERS (AIC_IRQS + PIN_IRQS) +#define MAX_HANDLERS (AIC_IRQS + PIN_IRQS) extern rt_uint32_t rt_interrupt_nest; @@ -38,38 +38,38 @@ rt_uint32_t at91_extern_irq; * The default interrupt priority levels (0 = lowest, 7 = highest). */ static rt_uint32_t at91sam9260_default_irq_priority[MAX_HANDLERS] = { - 7, /* Advanced Interrupt Controller */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A */ - 1, /* Parallel IO Controller B */ - 1, /* Parallel IO Controller C */ - 0, /* Analog-to-Digital Converter */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 0, /* Multimedia Card Interface */ - 2, /* USB Device Port */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 5, /* Serial Synchronous Controller */ - 0, - 0, - 0, /* Timer Counter 0 */ - 0, /* Timer Counter 1 */ - 0, /* Timer Counter 2 */ - 2, /* USB Host port */ - 3, /* Ethernet */ - 0, /* Image Sensor Interface */ - 5, /* USART 3 */ - 5, /* USART 4 */ - 5, /* USART 5 */ - 0, /* Timer Counter 3 */ - 0, /* Timer Counter 4 */ - 0, /* Timer Counter 5 */ - 0, /* Advanced Interrupt Controller */ - 0, /* Advanced Interrupt Controller */ - 0, /* Advanced Interrupt Controller */ + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 1, /* Parallel IO Controller A */ + 1, /* Parallel IO Controller B */ + 1, /* Parallel IO Controller C */ + 0, /* Analog-to-Digital Converter */ + 5, /* USART 0 */ + 5, /* USART 1 */ + 5, /* USART 2 */ + 0, /* Multimedia Card Interface */ + 2, /* USB Device Port */ + 6, /* Two-Wire Interface */ + 5, /* Serial Peripheral Interface 0 */ + 5, /* Serial Peripheral Interface 1 */ + 5, /* Serial Synchronous Controller */ + 0, + 0, + 0, /* Timer Counter 0 */ + 0, /* Timer Counter 1 */ + 0, /* Timer Counter 2 */ + 2, /* USB Host port */ + 3, /* Ethernet */ + 0, /* Image Sensor Interface */ + 5, /* USART 3 */ + 5, /* USART 4 */ + 5, /* USART 5 */ + 0, /* Timer Counter 3 */ + 0, /* Timer Counter 4 */ + 0, /* Timer Counter 5 */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ }; /** @@ -82,45 +82,45 @@ void rt_hw_interrupt_umask(int irq); rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param) { - rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); - return RT_NULL; + rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); + return RT_NULL; } rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector, void *param) { - rt_uint32_t isr, pio, irq_n; - void *parameter; - - if (vector == AT91SAM9260_ID_PIOA) - { - pio = AT91_PIOA; - irq_n = AIC_IRQS; - } - else if (vector == AT91SAM9260_ID_PIOB) - { - pio = AT91_PIOB; - irq_n = AIC_IRQS + 32; - } - else if (vector == AT91SAM9260_ID_PIOC) - { - pio = AT91_PIOC; - irq_n = AIC_IRQS + 32*2; - } - else - return RT_NULL; - isr = at91_sys_read(pio+PIO_ISR) & at91_sys_read(pio+PIO_IMR); - while (isr) - { - if (isr & 1) - { - parameter = irq_desc[irq_n].param; - irq_desc[irq_n].isr_handle(irq_n, parameter); - } - isr >>= 1; - irq_n++; - } - - return RT_NULL; + rt_uint32_t isr, pio, irq_n; + void *parameter; + + if (vector == AT91SAM9260_ID_PIOA) + { + pio = AT91_PIOA; + irq_n = AIC_IRQS; + } + else if (vector == AT91SAM9260_ID_PIOB) + { + pio = AT91_PIOB; + irq_n = AIC_IRQS + 32; + } + else if (vector == AT91SAM9260_ID_PIOC) + { + pio = AT91_PIOC; + irq_n = AIC_IRQS + 32*2; + } + else + return RT_NULL; + isr = at91_sys_read(pio+PIO_ISR) & at91_sys_read(pio+PIO_IMR); + while (isr) + { + if (isr & 1) + { + parameter = irq_desc[irq_n].param; + irq_desc[irq_n].handler(irq_n, parameter); + } + isr >>= 1; + irq_n++; + } + + return RT_NULL; } /* @@ -128,61 +128,61 @@ rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector, void *param) */ void at91_aic_init(rt_uint32_t *priority) { - rt_uint32_t i; - - /* - * The IVR is used by macro get_irqnr_and_base to read and verify. - * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. - */ - for (i = 0; i < AIC_IRQS; i++) { - /* Put irq number in Source Vector Register: */ - at91_sys_write(AT91_AIC_SVR(i), i); - /* Active Low interrupt, with the specified priority */ - at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); - //AT91_AIC_SRCTYPE_FALLING - - /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ - if (i < 8) - at91_sys_write(AT91_AIC_EOICR, 0); - } - - /* - * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS - * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU - */ - at91_sys_write(AT91_AIC_SPU, AIC_IRQS); - - /* No debugging in AIC: Debug (Protect) Control Register */ - at91_sys_write(AT91_AIC_DCR, 0); - - /* Disable and clear all interrupts initially */ - at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF); - at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF); + rt_uint32_t i; + + /* + * The IVR is used by macro get_irqnr_and_base to read and verify. + * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. + */ + for (i = 0; i < AIC_IRQS; i++) { + /* Put irq number in Source Vector Register: */ + at91_sys_write(AT91_AIC_SVR(i), i); + /* Active Low interrupt, with the specified priority */ + at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); + //AT91_AIC_SRCTYPE_FALLING + + /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ + if (i < 8) + at91_sys_write(AT91_AIC_EOICR, 0); + } + + /* + * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS + * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU + */ + at91_sys_write(AT91_AIC_SPU, AIC_IRQS); + + /* No debugging in AIC: Debug (Protect) Control Register */ + at91_sys_write(AT91_AIC_DCR, 0); + + /* Disable and clear all interrupts initially */ + at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF); + at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF); } static void at91_gpio_irq_init() { - int i, idx; - char *name[] = {"PIOA", "PIOB", "PIOC"}; - - at91_sys_write(AT91_PIOA+PIO_IDR, 0xffffffff); - at91_sys_write(AT91_PIOB+PIO_IDR, 0xffffffff); - at91_sys_write(AT91_PIOC+PIO_IDR, 0xffffffff); - - idx = AT91SAM9260_ID_PIOA; - for (i = 0; i < 3; i++) - { - rt_snprintf(irq_desc[idx].irq_name, RT_NAME_MAX - 1, name[i]); - irq_desc[idx].isr_handle = (rt_isr_handler_t)at91_gpio_irq_handle; - irq_desc[idx].param = RT_NULL; - irq_desc[idx].interrupt_cnt = 0; - idx++; - } - - rt_hw_interrupt_umask(AT91SAM9260_ID_PIOA); - rt_hw_interrupt_umask(AT91SAM9260_ID_PIOB); - rt_hw_interrupt_umask(AT91SAM9260_ID_PIOC); + int i, idx; + char *name[] = {"PIOA", "PIOB", "PIOC"}; + + at91_sys_write(AT91_PIOA+PIO_IDR, 0xffffffff); + at91_sys_write(AT91_PIOB+PIO_IDR, 0xffffffff); + at91_sys_write(AT91_PIOC+PIO_IDR, 0xffffffff); + + idx = AT91SAM9260_ID_PIOA; + for (i = 0; i < 3; i++) + { + rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, name[i]); + irq_desc[idx].handler = (rt_isr_handler_t)at91_gpio_irq_handle; + irq_desc[idx].param = RT_NULL; + irq_desc[idx].counter = 0; + idx++; + } + + rt_hw_interrupt_umask(AT91SAM9260_ID_PIOA); + rt_hw_interrupt_umask(AT91SAM9260_ID_PIOB); + rt_hw_interrupt_umask(AT91SAM9260_ID_PIOC); } @@ -191,56 +191,55 @@ static void at91_gpio_irq_init() */ void rt_hw_interrupt_init(void) { - rt_int32_t i; - register rt_uint32_t idx; - rt_uint32_t *priority = at91sam9260_default_irq_priority; - - at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) - | (1 << AT91SAM9260_ID_IRQ2); - - /* Initialize the AIC interrupt controller */ - at91_aic_init(priority); - - /* init exceptions table */ - for(idx=0; idx < MAX_HANDLERS; idx++) - { - rt_snprintf(irq_desc[idx].irq_name, RT_NAME_MAX - 1, "default"); - irq_desc[idx].isr_handle = (rt_isr_handler_t)rt_hw_interrupt_handle; - irq_desc[idx].param = RT_NULL; - irq_desc[idx].interrupt_cnt = 0; - } - - at91_gpio_irq_init(); - - /* init interrupt nest, and context in thread sp */ - rt_interrupt_nest = 0; - rt_interrupt_from_thread = 0; - rt_interrupt_to_thread = 0; - rt_thread_switch_interrupt_flag = 0; + rt_int32_t i; + register rt_uint32_t idx; + rt_uint32_t *priority = at91sam9260_default_irq_priority; + + at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) + | (1 << AT91SAM9260_ID_IRQ2); + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* init exceptions table */ + for(idx=0; idx < MAX_HANDLERS; idx++) + { + rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default"); + irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle; + irq_desc[idx].param = RT_NULL; + } + + at91_gpio_irq_init(); + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; } static void at91_gpio_irq_mask(int irq) { - rt_uint32_t pin, pio, bank; - - bank = (irq - AIC_IRQS)>>5; - - if (bank == 0) - { - pio = AT91_PIOA; - } - else if (bank == 1) - { - pio = AT91_PIOB; - } - else if (bank == 2) - { - pio = AT91_PIOC; - } - else - return; - pin = 1 << ((irq - AIC_IRQS) & 31); - at91_sys_write(pio+PIO_IDR, pin); + rt_uint32_t pin, pio, bank; + + bank = (irq - AIC_IRQS)>>5; + + if (bank == 0) + { + pio = AT91_PIOA; + } + else if (bank == 1) + { + pio = AT91_PIOB; + } + else if (bank == 2) + { + pio = AT91_PIOC; + } + else + return; + pin = 1 << ((irq - AIC_IRQS) & 31); + at91_sys_write(pio+PIO_IDR, pin); } /** @@ -249,39 +248,39 @@ static void at91_gpio_irq_mask(int irq) */ void rt_hw_interrupt_mask(int irq) { - if (irq >= AIC_IRQS) - { - at91_gpio_irq_mask(irq); - } - else - { - /* Disable interrupt on AIC */ - at91_sys_write(AT91_AIC_IDCR, 1 << irq); - } + if (irq >= AIC_IRQS) + { + at91_gpio_irq_mask(irq); + } + else + { + /* Disable interrupt on AIC */ + at91_sys_write(AT91_AIC_IDCR, 1 << irq); + } } static void at91_gpio_irq_umask(int irq) { - rt_uint32_t pin, pio, bank; - - bank = (irq - AIC_IRQS)>>5; - - if (bank == 0) - { - pio = AT91_PIOA; - } - else if (bank == 1) - { - pio = AT91_PIOB; - } - else if (bank == 2) - { - pio = AT91_PIOC; - } - else - return; - pin = 1 << ((irq - AIC_IRQS) & 31); - at91_sys_write(pio+PIO_IER, pin); + rt_uint32_t pin, pio, bank; + + bank = (irq - AIC_IRQS)>>5; + + if (bank == 0) + { + pio = AT91_PIOA; + } + else if (bank == 1) + { + pio = AT91_PIOB; + } + else if (bank == 2) + { + pio = AT91_PIOC; + } + else + return; + pin = 1 << ((irq - AIC_IRQS) & 31); + at91_sys_write(pio+PIO_IER, pin); } /** @@ -290,15 +289,15 @@ static void at91_gpio_irq_umask(int irq) */ void rt_hw_interrupt_umask(int irq) { - if (irq >= AIC_IRQS) - { - at91_gpio_irq_umask(irq); - } - else - { - /* Enable interrupt on AIC */ - at91_sys_write(AT91_AIC_IECR, 1 << irq); - } + if (irq >= AIC_IRQS) + { + at91_gpio_irq_umask(irq); + } + else + { + /* Enable interrupt on AIC */ + at91_sys_write(AT91_AIC_IECR, 1 << irq); + } } /** @@ -310,23 +309,22 @@ void rt_hw_interrupt_umask(int irq) * @return old handler */ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, - void *param, char *name) + void *param, char *name) { - rt_isr_handler_t old_handler = RT_NULL; - - if(vector < MAX_HANDLERS) - { - old_handler = irq_desc[vector].isr_handle; - if (handler != RT_NULL) - { - rt_snprintf(irq_desc[vector].irq_name, RT_NAME_MAX - 1, "%s", name); - irq_desc[vector].isr_handle = (rt_isr_handler_t)handler; - irq_desc[vector].param = param; - irq_desc[vector].interrupt_cnt = 0; - } - } - - return old_handler; + rt_isr_handler_t old_handler = RT_NULL; + + if(vector < MAX_HANDLERS) + { + old_handler = irq_desc[vector].handler; + if (handler != RT_NULL) + { + rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name); + irq_desc[vector].handler = (rt_isr_handler_t)handler; + irq_desc[vector].param = param; + } + } + + return old_handler; } /*@}*/ @@ -334,49 +332,49 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, static int at91_aic_set_type(unsigned irq, unsigned type) { - unsigned int smr, srctype; - - switch (type) { - case IRQ_TYPE_LEVEL_HIGH: - srctype = AT91_AIC_SRCTYPE_HIGH; - break; - case IRQ_TYPE_EDGE_RISING: - srctype = AT91_AIC_SRCTYPE_RISING; - break; - case IRQ_TYPE_LEVEL_LOW: - if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ - srctype = AT91_AIC_SRCTYPE_LOW; - else - return -1; - break; - case IRQ_TYPE_EDGE_FALLING: - if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ - srctype = AT91_AIC_SRCTYPE_FALLING; - else - return -1; - break; - default: - return -1; - } - - smr = at91_sys_read(AT91_AIC_SMR(irq)) & ~AT91_AIC_SRCTYPE; - at91_sys_write(AT91_AIC_SMR(irq), smr | srctype); - return 0; + unsigned int smr, srctype; + + switch (type) { + case IRQ_TYPE_LEVEL_HIGH: + srctype = AT91_AIC_SRCTYPE_HIGH; + break; + case IRQ_TYPE_EDGE_RISING: + srctype = AT91_AIC_SRCTYPE_RISING; + break; + case IRQ_TYPE_LEVEL_LOW: + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_LOW; + else + return -1; + break; + case IRQ_TYPE_EDGE_FALLING: + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_FALLING; + else + return -1; + break; + default: + return -1; + } + + smr = at91_sys_read(AT91_AIC_SMR(irq)) & ~AT91_AIC_SRCTYPE; + at91_sys_write(AT91_AIC_SMR(irq), smr | srctype); + return 0; } #ifdef RT_USING_FINSH void list_irq(void) { - int irq; - - rt_kprintf("number\tcount\tname\n"); - for (irq = 0; irq < MAX_HANDLERS; irq++) - { - if (rt_strncmp(irq_desc[irq].irq_name, "default", sizeof("default"))) - { - rt_kprintf("%02ld: %10ld %s\n", irq, irq_desc[irq].interrupt_cnt, irq_desc[irq].irq_name); - } - } + int irq; + + rt_kprintf("number\tcount\tname\n"); + for (irq = 0; irq < MAX_HANDLERS; irq++) + { + if (rt_strncmp(irq_desc[irq].name, "default", sizeof("default"))) + { + rt_kprintf("%02ld: %10ld %s\n", irq, irq_desc[irq].name); + } + } } #include diff --git a/libcpu/arm/at91sam926x/trap.c b/libcpu/arm/at91sam926x/trap.c index 841c8b68137743aef256e3da94bb864e27947fab..9be71ddcae8b496a0fa9c011bec40d3ffae20595 100755 --- a/libcpu/arm/at91sam926x/trap.c +++ b/libcpu/arm/at91sam926x/trap.c @@ -159,13 +159,13 @@ void rt_hw_trap_irq() //at91_sys_write(AT91_AIC_EOICR, 0x55555555); /* get interrupt service routine */ - isr_func = irq_desc[irq].isr_handle; + isr_func = irq_desc[irq].handler; param = irq_desc[irq].param; /* turn to interrupt service routine */ isr_func(irq, param); at91_sys_write(AT91_AIC_EOICR, 0x55555555); //EIOCR must be write any value after interrupt, or else can't response next interrupt - irq_desc[irq].interrupt_cnt++; + irq_desc[irq].counter ++; } void rt_hw_trap_fiq() diff --git a/libcpu/arm/cortex-m3/cpuport.c b/libcpu/arm/cortex-m3/cpuport.c index 60757d6b3d3b30d29d049aab71d68c0fd638f930..c96073a6a98ed4f24badbee2192196a80e7ed38c 100644 --- a/libcpu/arm/cortex-m3/cpuport.c +++ b/libcpu/arm/cortex-m3/cpuport.c @@ -162,28 +162,28 @@ void rt_hw_cpu_shutdown(void) #if defined(__CC_ARM) __asm int __rt_ffs(int value) { - CMP r0, #0x00 - BEQ exit - RBIT r0, r0 - CLZ r0, r0 - ADDS r0, r0, #0x01 + CMP r0, #0x00 + BEQ exit + RBIT r0, r0 + CLZ r0, r0 + ADDS r0, r0, #0x01 exit - BX lr + BX lr } #elif defined(__IAR_SYSTEMS_ICC__) int __rt_ffs(int value) { - if (value == 0) return value; - - __ASM("RBIT r0, r0"); - __ASM("CLZ r0, r0"); - __ASM("ADDS r0, r0, #0x01"); + if (value == 0) return value; + + __ASM("RBIT r0, r0"); + __ASM("CLZ r0, r0"); + __ASM("ADDS r0, r0, #0x01"); } #elif defined(__GNUC__) int __rt_ffs(int value) { - return __builtin_ffs(value); + return __builtin_ffs(value); } #endif