Skip to content

Commit f4e5359

Browse files
committed
GPIO: Use uintptr_t for gpio_irq_api context
The HAL gpio_irq_api stores object IDs, which serve as a form of context for the dispatch of the interrupt handler in the drivers level InterruptIn Class. The way this is achieved is that the InterruptIn Class casts its address to uint32_t, which is stored as the ID. This results in compilation failure when the size of an object pointer is greater than uint32_t, for example when building on a PC for unit testing. In order to allow Unit Testing of the InterruptIn Class, we replace the use of uint32_t with uintptr_t (type capable of holding a pointer), which allows portability and expresses intentions more clearly. In aid of this latter goal, we also replace the use of the name "id" with "context", to improve clarity - these are addresses of the context related to that callback.
1 parent a580c41 commit f4e5359

File tree

43 files changed

+233
-233
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+233
-233
lines changed

drivers/include/drivers/InterruptIn.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class InterruptIn : private NonCopyable<InterruptIn> {
129129
*/
130130
void disable_irq();
131131

132-
static void _irq_handler(uint32_t id, gpio_irq_event event);
132+
static void _irq_handler(uintptr_t context, gpio_irq_event event);
133133
#if !defined(DOXYGEN_ONLY)
134134
protected:
135135
gpio_t gpio;

drivers/source/InterruptIn.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ InterruptIn::InterruptIn(PinName pin, PinMode mode) :
4747

4848
void InterruptIn::irq_init(PinName pin)
4949
{
50-
gpio_irq_init(&gpio_irq, pin, (&InterruptIn::_irq_handler), (uint32_t)this);
50+
gpio_irq_init(&gpio_irq, pin, (&InterruptIn::_irq_handler), reinterpret_cast<uintptr_t>(this));
5151
}
5252

5353
InterruptIn::~InterruptIn()
@@ -95,9 +95,9 @@ void InterruptIn::fall(Callback<void()> func)
9595
core_util_critical_section_exit();
9696
}
9797

98-
void InterruptIn::_irq_handler(uint32_t id, gpio_irq_event event)
98+
void InterruptIn::_irq_handler(uintptr_t context, gpio_irq_event event)
9999
{
100-
InterruptIn *handler = (InterruptIn *)id;
100+
InterruptIn *handler = reinterpret_cast<InterruptIn *>(context);
101101
switch (event) {
102102
case IRQ_RISE:
103103
if (handler->_rise) {

hal/include/hal/gpio_irq_api.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ typedef enum {
4141
*/
4242
typedef struct gpio_irq_s gpio_irq_t;
4343

44-
typedef void (*gpio_irq_handler)(uint32_t id, gpio_irq_event event);
44+
typedef void (*gpio_irq_handler)(uintptr_t context, gpio_irq_event event);
4545

4646
/**
4747
* \defgroup hal_gpioirq GPIO IRQ HAL functions
@@ -75,10 +75,10 @@ typedef void (*gpio_irq_handler)(uint32_t id, gpio_irq_event event);
7575
* @param obj The GPIO object to initialize
7676
* @param pin The GPIO pin name
7777
* @param handler The handler to be attached to GPIO IRQ
78-
* @param id The object ID (id != 0, 0 is reserved)
78+
* @param context The context to be passed back to the handler (context != 0, 0 is reserved)
7979
* @return -1 if pin is NC, 0 otherwise
8080
*/
81-
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id);
81+
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uintptr_t context);
8282

8383
/** Release the GPIO IRQ PIN
8484
*

hal/tests/TESTS/mbed_hal_fpga_ci_test_shield/gpio_irq/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ using namespace utest::v1;
4040
MbedTester tester(DefaultFormFactor::pins(), DefaultFormFactor::restricted_pins());
4141

4242
static volatile uint32_t call_counter;
43-
void test_gpio_irq_handler(uint32_t id, gpio_irq_event event)
43+
void test_gpio_irq_handler(uintptr_t context, gpio_irq_event event)
4444
{
4545
call_counter++;
4646
}
@@ -63,8 +63,8 @@ void fpga_gpio_irq_test(PinName pin)
6363
gpio_init_in(&gpio, pin);
6464

6565
gpio_irq_t gpio_irq;
66-
uint32_t id = 123;
67-
TEST_ASSERT_EQUAL(0, gpio_irq_init(&gpio_irq, pin, test_gpio_irq_handler, id));
66+
uintptr_t context = 123;
67+
TEST_ASSERT_EQUAL(0, gpio_irq_init(&gpio_irq, pin, test_gpio_irq_handler, context));
6868

6969
gpio_irq_set(&gpio_irq, IRQ_RISE, true);
7070
gpio_irq_enable(&gpio_irq);

targets/TARGET_ARM_FM/TARGET_FVP_MPS2/gpio_irq_api.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#define CMSDK_GPIO_1 CMSDK_GPIO1
2525
#define PININT_IRQ 0
2626

27-
static uint32_t channel_ids[CHANNEL_NUM] = {0};
27+
static uintptr_t channel_contexts[CHANNEL_NUM] = {0};
2828
static gpio_irq_handler irq_handler;
2929

3030
static inline void handle_interrupt_in(uint32_t channel)
@@ -35,31 +35,31 @@ static inline void handle_interrupt_in(uint32_t channel)
3535
// * There is no user handler
3636
// * It is a level interrupt, not an edge interrupt
3737
if (ch_bit < 16) {
38-
if (((CMSDK_GPIO_0->INTSTATUS) == 0) || (channel_ids[channel] == 0) || ((CMSDK_GPIO_0->INTTYPESET) == 0)) {
38+
if (((CMSDK_GPIO_0->INTSTATUS) == 0) || (channel_contexts[channel] == 0) || ((CMSDK_GPIO_0->INTTYPESET) == 0)) {
3939
return;
4040
}
4141

4242
if ((CMSDK_GPIO_0->INTTYPESET & ch_bit) && (CMSDK_GPIO_0->INTPOLSET & ch_bit)) {
43-
irq_handler(channel_ids[channel], IRQ_RISE);
43+
irq_handler(channel_contexts[channel], IRQ_RISE);
4444
CMSDK_GPIO_0->INTPOLSET = ch_bit;
4545
}
4646
if ((CMSDK_GPIO_0->INTTYPESET & ch_bit) && ~(CMSDK_GPIO_0->INTPOLSET & ch_bit)) {
47-
irq_handler(channel_ids[channel], IRQ_FALL);
47+
irq_handler(channel_contexts[channel], IRQ_FALL);
4848
}
4949
CMSDK_GPIO_0->INTCLEAR = ch_bit;
5050
}
5151

5252
if (ch_bit >= 16) {
53-
if (((CMSDK_GPIO_1->INTSTATUS) == 0) || (channel_ids[channel] == 0) || ((CMSDK_GPIO_1->INTTYPESET) == 0)) {
53+
if (((CMSDK_GPIO_1->INTSTATUS) == 0) || (channel_contexts[channel] == 0) || ((CMSDK_GPIO_1->INTTYPESET) == 0)) {
5454
return;
5555
}
5656

5757
if ((CMSDK_GPIO_1->INTTYPESET & ch_bit) && (CMSDK_GPIO_1->INTPOLSET & ch_bit)) {
58-
irq_handler(channel_ids[channel], IRQ_RISE);
58+
irq_handler(channel_contexts[channel], IRQ_RISE);
5959
CMSDK_GPIO_1->INTPOLSET = ch_bit;
6060
}
6161
if ((CMSDK_GPIO_1->INTTYPESET & ch_bit) && ~(CMSDK_GPIO_1->INTPOLSET & ch_bit)) {
62-
irq_handler(channel_ids[channel], IRQ_FALL);
62+
irq_handler(channel_contexts[channel], IRQ_FALL);
6363
}
6464
CMSDK_GPIO_1->INTCLEAR = ch_bit;
6565
}
@@ -195,7 +195,7 @@ void gpio1_irq15(void)
195195
}
196196

197197

198-
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
198+
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uintptr_t context)
199199
{
200200
if (pin == NC) {
201201
return -1;
@@ -206,8 +206,8 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
206206
int found_free_channel = 0;
207207
int i = 0;
208208
for (i = 0; i < CHANNEL_NUM; i++) {
209-
if (channel_ids[i] == 0) {
210-
channel_ids[i] = id;
209+
if (channel_contexts[i] == 0) {
210+
channel_contexts[i] = context;
211211
obj->ch = i;
212212
found_free_channel = 1;
213213
break;

targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/gpio_irq_api.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
struct gpio_irq_handler_t {
2525
gpio_irq_handler handler;
2626
gpio_irq_event event;
27-
uint32_t id;
27+
uintptr_t context;
2828
};
2929

3030
/* Handlers registered */
@@ -69,7 +69,7 @@ static void handler(struct arm_gpio_dev_t* dev, uint32_t gpio_number,
6969

7070
exp_pin_number = exp_pin_base + pin_number;
7171

72-
gpio_irq[exp_pin_number].handler(gpio_irq[exp_pin_number].id,
72+
gpio_irq[exp_pin_number].handler(gpio_irq[exp_pin_number].context,
7373
gpio_irq[exp_pin_number].event);
7474
}
7575

@@ -102,7 +102,7 @@ void PORT3_ALL_IRQHandler(void)
102102
#endif /* ARM_GPIO3 */
103103

104104
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler,
105-
uint32_t id)
105+
uintptr_t context)
106106
{
107107
struct arm_gpio_dev_t *gpio_dev;
108108

@@ -146,7 +146,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler,
146146

147147
/* Save the handler and id into the global structure */
148148
gpio_irq[pin].handler = handler;
149-
gpio_irq[pin].id = id;
149+
gpio_irq[pin].context = context;
150150

151151
return 0;
152152
} else {

targets/TARGET_ARM_SSG/TARGET_MPS2/gpio_irq_api.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#define CMSDK_GPIO_1 CMSDK_GPIO1
2525
#define PININT_IRQ 0
2626

27-
static uint32_t channel_ids[CHANNEL_NUM] = {0};
27+
static uintptr_t channel_contexts[CHANNEL_NUM] = {0};
2828
static gpio_irq_handler irq_handler;
2929

3030
static inline void handle_interrupt_in(uint32_t channel) {
@@ -34,27 +34,27 @@ static inline void handle_interrupt_in(uint32_t channel) {
3434
// * There is no user handler
3535
// * It is a level interrupt, not an edge interrupt
3636
if (ch_bit <16){
37-
if ( ((CMSDK_GPIO_0->INTSTATUS) == 0) || (channel_ids[channel] == 0) || ((CMSDK_GPIO_0->INTTYPESET) == 0) ) return;
37+
if ( ((CMSDK_GPIO_0->INTSTATUS) == 0) || (channel_contexts[channel] == 0) || ((CMSDK_GPIO_0->INTTYPESET) == 0) ) return;
3838

3939
if ((CMSDK_GPIO_0->INTTYPESET & ch_bit) && (CMSDK_GPIO_0->INTPOLSET & ch_bit)) {
40-
irq_handler(channel_ids[channel], IRQ_RISE);
40+
irq_handler(channel_contexts[channel], IRQ_RISE);
4141
CMSDK_GPIO_0->INTPOLSET = ch_bit;
4242
}
4343
if ((CMSDK_GPIO_0->INTTYPESET & ch_bit) && ~(CMSDK_GPIO_0->INTPOLSET & ch_bit)) {
44-
irq_handler(channel_ids[channel], IRQ_FALL);
44+
irq_handler(channel_contexts[channel], IRQ_FALL);
4545
}
4646
CMSDK_GPIO_0->INTCLEAR = ch_bit;
4747
}
4848

4949
if (ch_bit>=16) {
50-
if ( ((CMSDK_GPIO_1->INTSTATUS) == 0) || (channel_ids[channel] == 0) || ((CMSDK_GPIO_1->INTTYPESET) == 0) ) return;
50+
if ( ((CMSDK_GPIO_1->INTSTATUS) == 0) || (channel_contexts[channel] == 0) || ((CMSDK_GPIO_1->INTTYPESET) == 0) ) return;
5151

5252
if ((CMSDK_GPIO_1->INTTYPESET & ch_bit) && (CMSDK_GPIO_1->INTPOLSET & ch_bit)) {
53-
irq_handler(channel_ids[channel], IRQ_RISE);
53+
irq_handler(channel_contexts[channel], IRQ_RISE);
5454
CMSDK_GPIO_1->INTPOLSET = ch_bit;
5555
}
5656
if ((CMSDK_GPIO_1->INTTYPESET & ch_bit) && ~(CMSDK_GPIO_1->INTPOLSET & ch_bit)) {
57-
irq_handler(channel_ids[channel], IRQ_FALL);
57+
irq_handler(channel_contexts[channel], IRQ_FALL);
5858
}
5959
CMSDK_GPIO_1->INTCLEAR = ch_bit;
6060
}
@@ -94,7 +94,7 @@ void gpio1_irq14(void) {handle_interrupt_in(30);}
9494
void gpio1_irq15(void) {handle_interrupt_in(31);}
9595

9696

97-
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
97+
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uintptr_t context) {
9898
if (pin == NC) {return -1;}
9999
else {
100100

@@ -103,8 +103,8 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
103103
int found_free_channel = 0;
104104
int i = 0;
105105
for (i=0; i<CHANNEL_NUM; i++) {
106-
if (channel_ids[i] == 0) {
107-
channel_ids[i] = id;
106+
if (channel_contexts[i] == 0) {
107+
channel_contexts[i] = context;
108108
obj->ch = i;
109109
found_free_channel = 1;
110110
break;

targets/TARGET_ARM_SSG/TARGET_MUSCA_B1/gpio_irq_api.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "mbed_error.h"
3030

3131
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler,
32-
uint32_t id)
32+
uintptr_t context)
3333
{
3434
/* Due to a HW limitation, GPIO in Musca-B1 is Secure only, in NS domain,
3535
* GPIO platform service is used. The current implementation of GPIO

targets/TARGET_ARM_SSG/TARGET_MUSCA_S1/gpio_irq_api.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "mbed_error.h"
3030

3131
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler,
32-
uint32_t id)
32+
uintptr_t context)
3333
{
3434
/* Due to a HW limitation, GPIO in Musca-S1 is Secure only, in NS domain,
3535
* GPIO platform service is used. The current implementation of GPIO

targets/TARGET_Ambiq_Micro/TARGET_Apollo3/device/gpio_irq_api.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, am_hal_gpio_intdir_e eIntD
3636
*/
3737
typedef struct gpio_irq_s gpio_irq_t;
3838

39-
typedef void (*gpio_irq_handler)(uint32_t id, gpio_irq_event event);
39+
typedef void (*gpio_irq_handler)(uintptr_t context, gpio_irq_event event);
4040
extern void am_gpio_isr(void);
4141
static ap3_gpio_irq_control_t gpio_irq_control[AP3_GPIO_MAX_PADS];
4242

@@ -62,18 +62,18 @@ static ap3_gpio_irq_control_t gpio_irq_control[AP3_GPIO_MAX_PADS];
6262
* @param obj The GPIO object to initialize
6363
* @param pin The GPIO pin name
6464
* @param handler The handler to be attached to GPIO IRQ
65-
* @param id The object ID (id != 0, 0 is reserved)
65+
* @param context The context to be passed back to the handler (context != 0, 0 is reserved)
6666
* @return -1 if pin is NC, 0 otherwise
6767
*/
68-
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id)
68+
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uintptr_t context)
6969
{
7070
//grab the correct irq control object
7171
ap3_gpio_irq_control_t *control = &gpio_irq_control[pin];
7272

7373
//Register locally
7474
control->pad = pin;
7575
control->handler = handler;
76-
control->id = id;
76+
control->id = context;
7777
control->events = IRQ_NONE;
7878

7979
//Attach to object

0 commit comments

Comments
 (0)