Skip to content

Commit b493a15

Browse files
committed
CAN: Use uintptr_t for can_irq_ids
The HAL can_api stores an array of IDs in order to dispatch interrupts to the correct CAN object. The drivers level CAN Class casts a pointer to itself to an uint32_t, which is stored as the ID and then cast back to a CAN * in order to call the correct handler. 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 CAN 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 810adf9 commit b493a15

File tree

13 files changed

+126
-126
lines changed

13 files changed

+126
-126
lines changed

drivers/include/drivers/CAN.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ class CAN
205205
*/
206206
void attach(Callback<void()> func, IrqType type = IrqType::RxIrq);
207207

208-
static void _irq_handler(uint32_t id, CanIrqType type);
208+
static void _irq_handler(uintptr_t context, CanIrqType type);
209209

210210
#if !defined(DOXYGEN_ONLY)
211211
protected:

drivers/source/CAN.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,28 @@ CAN::CAN(PinName rd, PinName td) : _can(), _irq()
2626
{
2727
// No lock needed in constructor
2828
can_init(&_can, rd, td);
29-
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
29+
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
3030
}
3131

3232
CAN::CAN(PinName rd, PinName td, int hz) : _can(), _irq()
3333
{
3434
// No lock needed in constructor
3535
can_init_freq(&_can, rd, td, hz);
36-
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
36+
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
3737
}
3838

3939
CAN::CAN(const can_pinmap_t &pinmap) : _can(), _irq()
4040
{
4141
// No lock needed in constructor
4242
can_init_direct(&_can, &pinmap);
43-
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
43+
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
4444
}
4545

4646
CAN::CAN(const can_pinmap_t &pinmap, int hz) : _can(), _irq()
4747
{
4848
// No lock needed in constructor
4949
can_init_freq_direct(&_can, &pinmap, hz);
50-
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
50+
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
5151
}
5252

5353
CAN::~CAN()
@@ -153,9 +153,9 @@ void CAN::attach(Callback<void()> func, IrqType type)
153153
unlock();
154154
}
155155

156-
void CAN::_irq_handler(uint32_t id, CanIrqType type)
156+
void CAN::_irq_handler(uintptr_t context, CanIrqType type)
157157
{
158-
CAN *handler = (CAN *)id;
158+
CAN *handler = reinterpret_cast<CAN *>(context);
159159
if (handler->_irq[type]) {
160160
handler->_irq[type].call();
161161
}

hal/include/hal/can_api.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ typedef struct {
6363
int td_function;
6464
} can_pinmap_t;
6565

66-
typedef void (*can_irq_handler)(uint32_t id, CanIrqType type);
66+
typedef void (*can_irq_handler)(uintptr_t context, CanIrqType type);
6767

6868
typedef struct can_s can_t;
6969

@@ -74,7 +74,7 @@ void can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int h
7474
void can_free(can_t *obj);
7575
int can_frequency(can_t *obj, int hz);
7676

77-
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id);
77+
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context);
7878
void can_irq_free(can_t *obj);
7979
void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable);
8080

targets/TARGET_GigaDevice/TARGET_GD32F30X/can_api.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
/* CAN1 interrupt vector number */
3939
#define CAN1_IRQ_BASE_NUM 63
4040

41-
static uint32_t can_irq_ids[2] = {0};
41+
static uintptr_t can_irq_contexts[2] = {0};
4242
static can_irq_handler irq_callback;
4343

4444
/** CAN interrupt handle .
@@ -66,13 +66,13 @@ static void dev_can_irq_handle(uint32_t periph, int id)
6666

6767
/* CAN transmit complete interrupt handle */
6868
if (flag0 || flag1 || flag2) {
69-
irq_callback(can_irq_ids[id], IRQ_TX);
69+
irq_callback(can_irq_contexts[id], IRQ_TX);
7070
}
7171

7272
/* CAN receive complete interrupt handle */
7373
if (CAN_INTEN_RFNEIE0 == (CAN_INTEN(periph) & CAN_INTEN_RFNEIE0)) {
7474
if (0 != can_receive_message_length_get(periph, CAN_FIFO0)) {
75-
irq_callback(can_irq_ids[id], IRQ_RX);
75+
irq_callback(can_irq_contexts[id], IRQ_RX);
7676
}
7777
}
7878

@@ -81,18 +81,18 @@ static void dev_can_irq_handle(uint32_t periph, int id)
8181
/* passive error interrupt handle */
8282
if (CAN_INTEN_PERRIE == (CAN_INTEN(periph) & CAN_INTEN_PERRIE)) {
8383
if (SET == can_flag_get(periph, CAN_FLAG_PERR)) {
84-
irq_callback(can_irq_ids[id], IRQ_PASSIVE);
84+
irq_callback(can_irq_contexts[id], IRQ_PASSIVE);
8585
}
8686
}
8787

8888
/* bus-off interrupt handle */
8989
if (CAN_INTEN_BOIE == (CAN_INTEN(periph) & CAN_INTEN_BOIE)) {
9090
if (SET == can_flag_get(periph, CAN_FLAG_BOERR)) {
91-
irq_callback(can_irq_ids[id], IRQ_BUS);
91+
irq_callback(can_irq_contexts[id], IRQ_BUS);
9292
}
9393
}
9494

95-
irq_callback(can_irq_ids[id], IRQ_ERROR);
95+
irq_callback(can_irq_contexts[id], IRQ_ERROR);
9696
}
9797
}
9898

@@ -330,10 +330,10 @@ int can_frequency(can_t *obj, int hz)
330330
* @param handler the interrupt callback.
331331
* @param id the CANx index.
332332
*/
333-
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
333+
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
334334
{
335335
irq_callback = handler;
336-
can_irq_ids[obj->index] = id;
336+
can_irq_contexts[obj->index] = context;
337337
}
338338

339339
/** disable the interrupt.
@@ -351,7 +351,7 @@ void can_irq_free(can_t *obj)
351351
CAN_INTEN_PERRIE | CAN_INTEN_BOIE | CAN_INTEN_ERRIE);
352352
}
353353

354-
can_irq_ids[obj->index] = 0;
354+
can_irq_contexts[obj->index] = 0;
355355
}
356356

357357
/** Set the interrupt handle.

targets/TARGET_GigaDevice/TARGET_GD32F4XX/can_api.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
/* CAN1 interrupt vector number */
3939
#define CAN1_IRQ_BASE_NUM 63
4040

41-
static uint32_t can_irq_ids[2] = {0};
41+
static uintptr_t can_irq_contexts[2] = {0};
4242
static can_irq_handler irq_callback;
4343

4444
/** CAN interrupt handle .
@@ -66,13 +66,13 @@ static void dev_can_irq_handle(uint32_t periph, int id)
6666

6767
/* CAN transmit complete interrupt handle */
6868
if (flag0 || flag1 || flag2) {
69-
irq_callback(can_irq_ids[id], IRQ_TX);
69+
irq_callback(can_irq_contexts[id], IRQ_TX);
7070
}
7171

7272
/* CAN receive complete interrupt handle */
7373
if (CAN_INTEN_RFNEIE0 == (CAN_INTEN(periph) & CAN_INTEN_RFNEIE0)) {
7474
if (0 != can_receive_message_length_get(periph, CAN_FIFO0)) {
75-
irq_callback(can_irq_ids[id], IRQ_RX);
75+
irq_callback(can_irq_contexts[id], IRQ_RX);
7676
}
7777
}
7878

@@ -81,18 +81,18 @@ static void dev_can_irq_handle(uint32_t periph, int id)
8181
/* passive error interrupt handle */
8282
if (CAN_INTEN_PERRIE == (CAN_INTEN(periph) & CAN_INTEN_PERRIE)) {
8383
if (SET == can_flag_get(periph, CAN_FLAG_PERR)) {
84-
irq_callback(can_irq_ids[id], IRQ_PASSIVE);
84+
irq_callback(can_irq_contexts[id], IRQ_PASSIVE);
8585
}
8686
}
8787

8888
/* bus-off interrupt handle */
8989
if (CAN_INTEN_BOIE == (CAN_INTEN(periph) & CAN_INTEN_BOIE)) {
9090
if (SET == can_flag_get(periph, CAN_FLAG_BOERR)) {
91-
irq_callback(can_irq_ids[id], IRQ_BUS);
91+
irq_callback(can_irq_contexts[id], IRQ_BUS);
9292
}
9393
}
9494

95-
irq_callback(can_irq_ids[id], IRQ_ERROR);
95+
irq_callback(can_irq_contexts[id], IRQ_ERROR);
9696
}
9797
}
9898

@@ -331,10 +331,10 @@ int can_frequency(can_t *obj, int hz)
331331
* @param handler the interrupt callback.
332332
* @param id the CANx index.
333333
*/
334-
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
334+
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
335335
{
336336
irq_callback = handler;
337-
can_irq_ids[obj->index] = id;
337+
can_irq_contexts[obj->index] = context;
338338
}
339339

340340
/** disable the interrupt.
@@ -352,7 +352,7 @@ void can_irq_free(can_t *obj)
352352
CAN_INTEN_PERRIE | CAN_INTEN_BOIE | CAN_INTEN_ERRIE);
353353
}
354354

355-
can_irq_ids[obj->index] = 0;
355+
can_irq_contexts[obj->index] = 0;
356356
}
357357

358358
/** Set the interrupt handle.

targets/TARGET_NUVOTON/TARGET_M451/can_api.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#define NU_CAN_DEBUG 0
3232
#define CAN_NUM 1
3333

34-
static uint32_t can_irq_ids[CAN_NUM] = {0};
34+
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
3535
static can_irq_handler can0_irq_handler;
3636

3737

@@ -125,34 +125,34 @@ static void can_irq(CANName name, int id)
125125
/**************************/
126126
if(can->STATUS & CAN_STATUS_RXOK_Msk) {
127127
can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/
128-
can0_irq_handler(can_irq_ids[id], IRQ_RX);
128+
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
129129
}
130130

131131
if(can->STATUS & CAN_STATUS_TXOK_Msk) {
132132
can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/
133-
can0_irq_handler(can_irq_ids[id], IRQ_TX);
133+
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
134134
}
135135

136136
/**************************/
137137
/* Error Status interrupt */
138138
/**************************/
139139
if(can->STATUS & CAN_STATUS_EWARN_Msk) {
140-
can0_irq_handler(can_irq_ids[id], IRQ_ERROR);
140+
can0_irq_handler(can_irq_contexts[id], IRQ_ERROR);
141141
}
142142

143143
if(can->STATUS & CAN_STATUS_BOFF_Msk) {
144-
can0_irq_handler(can_irq_ids[id], IRQ_BUS);
144+
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
145145
}
146146
} else if (u8IIDRstatus!=0) {
147147

148-
can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
148+
can0_irq_handler(can_irq_contexts[id], IRQ_OVERRUN);
149149

150150
CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */
151151

152152
} else if(can->WU_STATUS == 1) {
153153

154154
can->WU_STATUS = 0; /* Write '0' to clear */
155-
can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
155+
can0_irq_handler(can_irq_contexts[id], IRQ_WAKEUP);
156156
}
157157
}
158158

@@ -161,17 +161,17 @@ void CAN0_IRQHandler(void)
161161
can_irq(CAN_0, 0);
162162
}
163163

164-
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
164+
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
165165
{
166166
can0_irq_handler = handler;
167-
can_irq_ids[obj->index] = id;
167+
can_irq_contexts[obj->index] = context;
168168
}
169169

170170
void can_irq_free(can_t *obj)
171171
{
172172
CAN_DisableInt((CAN_T *)NU_MODBASE(obj->can), (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk));
173173

174-
can_irq_ids[obj->index] = 0;
174+
can_irq_contexts[obj->index] = 0;
175175

176176
NVIC_DisableIRQ(CAN0_IRQn);
177177
}

targets/TARGET_NUVOTON/TARGET_M480/can_api.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#define NU_CAN_DEBUG 0
3535
#define CAN_NUM 2
3636

37-
static uint32_t can_irq_ids[CAN_NUM] = {0};
37+
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
3838
static can_irq_handler can0_irq_handler;
3939
static can_irq_handler can1_irq_handler;
4040

@@ -140,17 +140,17 @@ static void can_irq(CANName name, int id)
140140
if(can->STATUS & CAN_STATUS_RXOK_Msk) {
141141
can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/
142142
if(id)
143-
can1_irq_handler(can_irq_ids[id], IRQ_RX);
143+
can1_irq_handler(can_irq_contexts[id], IRQ_RX);
144144
else
145-
can0_irq_handler(can_irq_ids[id], IRQ_RX);
145+
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
146146
}
147147

148148
if(can->STATUS & CAN_STATUS_TXOK_Msk) {
149149
can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/
150150
if(id)
151-
can1_irq_handler(can_irq_ids[id], IRQ_TX);
151+
can1_irq_handler(can_irq_contexts[id], IRQ_TX);
152152
else
153-
can0_irq_handler(can_irq_ids[id], IRQ_TX);
153+
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
154154

155155
}
156156

@@ -159,33 +159,33 @@ static void can_irq(CANName name, int id)
159159
/**************************/
160160
if(can->STATUS & CAN_STATUS_EWARN_Msk) {
161161
if(id)
162-
can1_irq_handler(can_irq_ids[id], IRQ_ERROR);
162+
can1_irq_handler(can_irq_contexts[id], IRQ_ERROR);
163163
else
164-
can0_irq_handler(can_irq_ids[id], IRQ_ERROR);
164+
can0_irq_handler(can_irq_contexts[id], IRQ_ERROR);
165165
}
166166

167167
if(can->STATUS & CAN_STATUS_BOFF_Msk) {
168168
if(id)
169-
can1_irq_handler(can_irq_ids[id], IRQ_BUS);
169+
can1_irq_handler(can_irq_contexts[id], IRQ_BUS);
170170
else
171-
can0_irq_handler(can_irq_ids[id], IRQ_BUS);
171+
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
172172
}
173173
} else if (u8IIDRstatus!=0) {
174174

175175
if(id)
176-
can1_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
176+
can1_irq_handler(can_irq_contexts[id], IRQ_OVERRUN);
177177
else
178-
can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
178+
can0_irq_handler(can_irq_contexts[id], IRQ_OVERRUN);
179179

180180
CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */
181181

182182
} else if(can->WU_STATUS == 1) {
183183

184184
can->WU_STATUS = 0; /* Write '0' to clear */
185185
if(id)
186-
can1_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
186+
can1_irq_handler(can_irq_contexts[id], IRQ_WAKEUP);
187187
else
188-
can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
188+
can0_irq_handler(can_irq_contexts[id], IRQ_WAKEUP);
189189
}
190190
}
191191

@@ -199,21 +199,21 @@ void CAN1_IRQHandler(void)
199199
can_irq(CAN_1, 1);
200200
}
201201

202-
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
202+
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
203203
{
204204
if(obj->index)
205205
can1_irq_handler = handler;
206206
else
207207
can0_irq_handler = handler;
208-
can_irq_ids[obj->index] = id;
208+
can_irq_contexts[obj->index] = context;
209209

210210
}
211211

212212
void can_irq_free(can_t *obj)
213213
{
214214
CAN_DisableInt((CAN_T *)NU_MODBASE(obj->can), (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk));
215215

216-
can_irq_ids[obj->index] = 0;
216+
can_irq_contexts[obj->index] = 0;
217217

218218
if(!obj->index)
219219
NVIC_DisableIRQ(CAN0_IRQn);

0 commit comments

Comments
 (0)