Skip to content

Commit 11d340f

Browse files
alexanderwachtercarlescufi
authored andcommitted
drivers: can: m_can: fix alignmed issues
Make sure that all access to the msg_sram is 32 bit aligned. Signed-off-by: Alexander Wachter <alexander@wachter.cloud>
1 parent 2269408 commit 11d340f

File tree

2 files changed

+52
-41
lines changed

2 files changed

+52
-41
lines changed

drivers/can/can_mcan.c

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,34 @@ LOG_MODULE_DECLARE(can_driver, CONFIG_CAN_LOG_LEVEL);
2323
#define MCAN_MAX_DLC CAN_MAX_DLC
2424
#endif
2525

26+
static void memcpy32_volatile(volatile void *dst_, const volatile void *src_,
27+
size_t len)
28+
{
29+
volatile uint32_t *dst = dst_;
30+
const volatile uint32_t *src = src_;
31+
32+
__ASSERT(len % 4 == 0, "len must be a multiple of 4!");
33+
len /= sizeof(uint32_t);
34+
35+
while (len--) {
36+
*dst = *src;
37+
++dst;
38+
++src;
39+
}
40+
}
41+
42+
static void memset32_volatile(volatile void *dst_, uint32_t val, size_t len)
43+
{
44+
volatile uint32_t *dst = dst_;
45+
46+
__ASSERT(len % 4 == 0, "len must be a multiple of 4!");
47+
len /= sizeof(uint32_t);
48+
49+
while (len--) {
50+
*dst++ = val;
51+
}
52+
}
53+
2654
static int can_exit_sleep_mode(struct can_mcan_reg *can)
2755
{
2856
uint32_t start_time;
@@ -386,12 +414,7 @@ int can_mcan_init(const struct device *dev, const struct can_mcan_config *cfg,
386414
}
387415

388416
/* No memset because only aligned ptr are allowed */
389-
for (uint32_t *ptr = (uint32_t *)msg_ram;
390-
ptr < (uint32_t *)msg_ram +
391-
sizeof(struct can_mcan_msg_sram) / sizeof(uint32_t);
392-
ptr++) {
393-
*ptr = 0;
394-
}
417+
memset32_volatile(msg_ram, 0, sizeof(struct can_mcan_msg_sram));
395418

396419
return 0;
397420
}
@@ -483,15 +506,15 @@ static void can_mcan_get_message(struct can_mcan_data *data,
483506
uint32_t get_idx, filt_idx;
484507
struct zcan_frame frame;
485508
can_rx_callback_t cb;
486-
volatile uint32_t *src, *dst, *end;
487509
int data_length;
488510
void *cb_arg;
489511
struct can_mcan_rx_fifo_hdr hdr;
490512

491513
while ((*fifo_status_reg & CAN_MCAN_RXF0S_F0FL)) {
492514
get_idx = (*fifo_status_reg & CAN_MCAN_RXF0S_F0GI) >>
493515
CAN_MCAN_RXF0S_F0GI_POS;
494-
hdr = fifo[get_idx].hdr;
516+
memcpy32_volatile(&hdr, &fifo[get_idx].hdr,
517+
sizeof(struct can_mcan_rx_fifo_hdr));
495518

496519
if (hdr.xtd) {
497520
frame.id = hdr.ext_id;
@@ -522,13 +545,8 @@ static void can_mcan_get_message(struct can_mcan_data *data,
522545
data_length = can_dlc_to_bytes(frame.dlc);
523546
if (data_length <= sizeof(frame.data)) {
524547
/* data needs to be written in 32 bit blocks!*/
525-
for (src = fifo[get_idx].data_32,
526-
dst = frame.data_32,
527-
end = dst + CAN_DIV_CEIL(data_length, sizeof(uint32_t));
528-
dst < end;
529-
src++, dst++) {
530-
*dst = *src;
531-
}
548+
memcpy32_volatile(frame.data_32, fifo[get_idx].data_32,
549+
ROUND_UP(data_length, sizeof(uint32_t)));
532550

533551
if (frame.id_type == CAN_STANDARD_IDENTIFIER) {
534552
LOG_DBG("Frame on filter %d, ID: 0x%x",
@@ -644,8 +662,6 @@ int can_mcan_send(const struct can_mcan_config *cfg,
644662
uint32_t put_idx;
645663
int ret;
646664
struct can_mcan_mm mm;
647-
volatile uint32_t *dst, *end;
648-
const uint32_t *src;
649665

650666
LOG_DBG("Sending %d bytes. Id: 0x%x, ID type: %s %s %s %s",
651667
data_length, frame->id,
@@ -693,15 +709,9 @@ int can_mcan_send(const struct can_mcan_config *cfg,
693709
tx_hdr.ext_id = frame->id;
694710
}
695711

696-
msg_ram->tx_buffer[put_idx].hdr = tx_hdr;
697-
698-
for (src = frame->data_32,
699-
dst = msg_ram->tx_buffer[put_idx].data_32,
700-
end = dst + CAN_DIV_CEIL(data_length, sizeof(uint32_t));
701-
dst < end;
702-
src++, dst++) {
703-
*dst = *src;
704-
}
712+
memcpy32_volatile(&msg_ram->tx_buffer[put_idx].hdr, &tx_hdr, sizeof(tx_hdr));
713+
memcpy32_volatile(msg_ram->tx_buffer[put_idx].data_32, frame->data_32,
714+
ROUND_UP(data_length, 4));
705715

706716
data->tx_fin_cb[put_idx] = callback;
707717
data->tx_fin_cb_arg[put_idx] = user_data;
@@ -758,7 +768,8 @@ int can_mcan_attach_std(struct can_mcan_data *data,
758768
filter_element.sfce = filter_nr & 0x01 ? CAN_MCAN_FCE_FIFO1 :
759769
CAN_MCAN_FCE_FIFO0;
760770

761-
msg_ram->std_filt[filter_nr] = filter_element;
771+
memcpy32_volatile(&msg_ram->std_filt[filter_nr], &filter_element,
772+
sizeof(struct can_mcan_std_filter));
762773

763774
k_mutex_unlock(&data->inst_mutex);
764775

@@ -817,7 +828,8 @@ static int can_mcan_attach_ext(struct can_mcan_data *data,
817828
filter_element.efce = filter_nr & 0x01 ? CAN_MCAN_FCE_FIFO1 :
818829
CAN_MCAN_FCE_FIFO0;
819830

820-
msg_ram->ext_filt[filter_nr] = filter_element;
831+
memcpy32_volatile(&msg_ram->ext_filt[filter_nr], &filter_element,
832+
sizeof(struct can_mcan_ext_filter));
821833

822834
k_mutex_unlock(&data->inst_mutex);
823835

@@ -871,9 +883,6 @@ int can_mcan_attach_isr(struct can_mcan_data *data,
871883
void can_mcan_detach(struct can_mcan_data *data,
872884
struct can_mcan_msg_sram *msg_ram, int filter_nr)
873885
{
874-
const struct can_mcan_ext_filter ext_filter = {0};
875-
const struct can_mcan_std_filter std_filter = {0};
876-
877886
k_mutex_lock(&data->inst_mutex, K_FOREVER);
878887
if (filter_nr >= NUM_STD_FILTER_DATA) {
879888
filter_nr -= NUM_STD_FILTER_DATA;
@@ -882,10 +891,12 @@ void can_mcan_detach(struct can_mcan_data *data,
882891
return;
883892
}
884893

885-
msg_ram->ext_filt[filter_nr] = ext_filter;
894+
memset32_volatile(&msg_ram->ext_filt[filter_nr], 0,
895+
sizeof(struct can_mcan_ext_filter));
886896
data->rx_cb_ext[filter_nr] = NULL;
887897
} else {
888-
msg_ram->std_filt[filter_nr] = std_filter;
898+
memset32_volatile(&msg_ram->std_filt[filter_nr], 0,
899+
sizeof(struct can_mcan_std_filter));
889900
data->rx_cb_std[filter_nr] = NULL;
890901
}
891902

drivers/can/can_mcan.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ struct can_mcan_rx_fifo_hdr {
4848
volatile uint32_t res : 2; /* Reserved */
4949
volatile uint32_t fidx : 7; /* Filter Index */
5050
volatile uint32_t anmf : 1; /* Accepted non-matching frame */
51-
} __packed;
51+
} __packed __aligned(4);
5252

5353
struct can_mcan_rx_fifo {
5454
struct can_mcan_rx_fifo_hdr hdr;
5555
union {
5656
volatile uint8_t data[64];
5757
volatile uint32_t data_32[16];
5858
};
59-
} __packed;
59+
} __packed __aligned(4);
6060

6161
struct can_mcan_mm {
6262
volatile uint8_t idx : 5;
@@ -84,15 +84,15 @@ struct can_mcan_tx_buffer_hdr {
8484
volatile uint8_t res2 : 1; /* Reserved */
8585
volatile uint8_t efc : 1; /* Event FIFO control (Store Tx events) */
8686
struct can_mcan_mm mm; /* Message marker */
87-
} __packed;
87+
} __packed __aligned(4);
8888

8989
struct can_mcan_tx_buffer {
9090
struct can_mcan_tx_buffer_hdr hdr;
9191
union {
9292
volatile uint8_t data[64];
9393
volatile uint32_t data_32[16];
9494
};
95-
} __packed;
95+
} __packed __aligned(4);
9696

9797
#define CAN_MCAN_TE_TX 0x1 /* TX event */
9898
#define CAN_MCAN_TE_TXC 0x2 /* TX event in spite of cancellation */
@@ -109,7 +109,7 @@ struct can_mcan_tx_event_fifo {
109109
volatile uint8_t fdf : 1; /* FD Format */
110110
volatile uint8_t et : 2; /* Event type */
111111
struct can_mcan_mm mm; /* Message marker */
112-
} __packed;
112+
} __packed __aligned(4);
113113

114114
#define CAN_MCAN_FCE_DISABLE 0x0
115115
#define CAN_MCAN_FCE_FIFO0 0x1
@@ -130,7 +130,7 @@ struct can_mcan_std_filter {
130130
volatile uint32_t id1 : 11;
131131
volatile uint32_t sfce : 3; /* Filter config */
132132
volatile uint32_t sft : 2; /* Filter type */
133-
} __packed;
133+
} __packed __aligned(4);
134134

135135
#define CAN_MCAN_EFT_RANGE_XIDAM 0x0
136136
#define CAN_MCAN_EFT_DUAL 0x1
@@ -143,7 +143,7 @@ struct can_mcan_ext_filter {
143143
volatile uint32_t id2 : 29; /* ID2 for dual or range, mask otherwise */
144144
volatile uint32_t res : 1;
145145
volatile uint32_t eft : 2; /* Filter type */
146-
} __packed;
146+
} __packed __aligned(4);
147147

148148
struct can_mcan_msg_sram {
149149
volatile struct can_mcan_std_filter std_filt[NUM_STD_FILTER_ELEMENTS];
@@ -153,7 +153,7 @@ struct can_mcan_msg_sram {
153153
volatile struct can_mcan_rx_fifo rx_buffer[NUM_RX_BUF_ELEMENTS];
154154
volatile struct can_mcan_tx_event_fifo tx_event_fifo[NUM_TX_BUF_ELEMENTS];
155155
volatile struct can_mcan_tx_buffer tx_buffer[NUM_TX_BUF_ELEMENTS];
156-
} __packed;
156+
} __packed __aligned(4);
157157

158158
struct can_mcan_data {
159159
struct k_mutex inst_mutex;

0 commit comments

Comments
 (0)