Skip to content

Commit 7aa38b4

Browse files
alexanderwachtercfriedt
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 6dd320f commit 7aa38b4

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;
@@ -389,12 +417,7 @@ int can_mcan_init(const struct device *dev, const struct can_mcan_config *cfg,
389417
}
390418

391419
/* No memset because only aligned ptr are allowed */
392-
for (uint32_t *ptr = (uint32_t *)msg_ram;
393-
ptr < (uint32_t *)msg_ram +
394-
sizeof(struct can_mcan_msg_sram) / sizeof(uint32_t);
395-
ptr++) {
396-
*ptr = 0;
397-
}
420+
memset32_volatile(msg_ram, 0, sizeof(struct can_mcan_msg_sram));
398421

399422
return 0;
400423
}
@@ -486,15 +509,15 @@ static void can_mcan_get_message(struct can_mcan_data *data,
486509
uint32_t get_idx, filt_idx;
487510
struct zcan_frame frame;
488511
can_rx_callback_t cb;
489-
volatile uint32_t *src, *dst, *end;
490512
int data_length;
491513
void *cb_arg;
492514
struct can_mcan_rx_fifo_hdr hdr;
493515

494516
while ((*fifo_status_reg & CAN_MCAN_RXF0S_F0FL)) {
495517
get_idx = (*fifo_status_reg & CAN_MCAN_RXF0S_F0GI) >>
496518
CAN_MCAN_RXF0S_F0GI_POS;
497-
hdr = fifo[get_idx].hdr;
519+
memcpy32_volatile(&hdr, &fifo[get_idx].hdr,
520+
sizeof(struct can_mcan_rx_fifo_hdr));
498521

499522
if (hdr.xtd) {
500523
frame.id = hdr.ext_id;
@@ -525,13 +548,8 @@ static void can_mcan_get_message(struct can_mcan_data *data,
525548
data_length = can_dlc_to_bytes(frame.dlc);
526549
if (data_length <= sizeof(frame.data)) {
527550
/* data needs to be written in 32 bit blocks!*/
528-
for (src = fifo[get_idx].data_32,
529-
dst = frame.data_32,
530-
end = dst + CAN_DIV_CEIL(data_length, sizeof(uint32_t));
531-
dst < end;
532-
src++, dst++) {
533-
*dst = *src;
534-
}
551+
memcpy32_volatile(frame.data_32, fifo[get_idx].data_32,
552+
ROUND_UP(data_length, sizeof(uint32_t)));
535553

536554
if (frame.id_type == CAN_STANDARD_IDENTIFIER) {
537555
LOG_DBG("Frame on filter %d, ID: 0x%x",
@@ -647,8 +665,6 @@ int can_mcan_send(const struct can_mcan_config *cfg,
647665
uint32_t put_idx;
648666
int ret;
649667
struct can_mcan_mm mm;
650-
volatile uint32_t *dst, *end;
651-
const uint32_t *src;
652668

653669
LOG_DBG("Sending %d bytes. Id: 0x%x, ID type: %s %s %s %s",
654670
data_length, frame->id,
@@ -696,15 +712,9 @@ int can_mcan_send(const struct can_mcan_config *cfg,
696712
tx_hdr.ext_id = frame->id;
697713
}
698714

699-
msg_ram->tx_buffer[put_idx].hdr = tx_hdr;
700-
701-
for (src = frame->data_32,
702-
dst = msg_ram->tx_buffer[put_idx].data_32,
703-
end = dst + CAN_DIV_CEIL(data_length, sizeof(uint32_t));
704-
dst < end;
705-
src++, dst++) {
706-
*dst = *src;
707-
}
715+
memcpy32_volatile(&msg_ram->tx_buffer[put_idx].hdr, &tx_hdr, sizeof(tx_hdr));
716+
memcpy32_volatile(msg_ram->tx_buffer[put_idx].data_32, frame->data_32,
717+
ROUND_UP(data_length, 4));
708718

709719
data->tx_fin_cb[put_idx] = callback;
710720
data->tx_fin_cb_arg[put_idx] = callback_arg;
@@ -761,7 +771,8 @@ int can_mcan_attach_std(struct can_mcan_data *data,
761771
filter_element.sfce = filter_nr & 0x01 ? CAN_MCAN_FCE_FIFO1 :
762772
CAN_MCAN_FCE_FIFO0;
763773

764-
msg_ram->std_filt[filter_nr] = filter_element;
774+
memcpy32_volatile(&msg_ram->std_filt[filter_nr], &filter_element,
775+
sizeof(struct can_mcan_std_filter));
765776

766777
k_mutex_unlock(&data->inst_mutex);
767778

@@ -820,7 +831,8 @@ static int can_mcan_attach_ext(struct can_mcan_data *data,
820831
filter_element.efce = filter_nr & 0x01 ? CAN_MCAN_FCE_FIFO1 :
821832
CAN_MCAN_FCE_FIFO0;
822833

823-
msg_ram->ext_filt[filter_nr] = filter_element;
834+
memcpy32_volatile(&msg_ram->ext_filt[filter_nr], &filter_element,
835+
sizeof(struct can_mcan_ext_filter));
824836

825837
k_mutex_unlock(&data->inst_mutex);
826838

@@ -874,9 +886,6 @@ int can_mcan_attach_isr(struct can_mcan_data *data,
874886
void can_mcan_detach(struct can_mcan_data *data,
875887
struct can_mcan_msg_sram *msg_ram, int filter_nr)
876888
{
877-
const struct can_mcan_ext_filter ext_filter = {0};
878-
const struct can_mcan_std_filter std_filter = {0};
879-
880889
k_mutex_lock(&data->inst_mutex, K_FOREVER);
881890
if (filter_nr >= NUM_STD_FILTER_DATA) {
882891
filter_nr -= NUM_STD_FILTER_DATA;
@@ -885,10 +894,12 @@ void can_mcan_detach(struct can_mcan_data *data,
885894
return;
886895
}
887896

888-
msg_ram->ext_filt[filter_nr] = ext_filter;
897+
memset32_volatile(&msg_ram->ext_filt[filter_nr], 0,
898+
sizeof(struct can_mcan_ext_filter));
889899
data->rx_cb_ext[filter_nr] = NULL;
890900
} else {
891-
msg_ram->std_filt[filter_nr] = std_filter;
901+
memset32_volatile(&msg_ram->std_filt[filter_nr], 0,
902+
sizeof(struct can_mcan_std_filter));
892903
data->rx_cb_std[filter_nr] = NULL;
893904
}
894905

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)