libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::STM32CAN Class Reference

STM32CAN 类,用于处理 STM32 系统的 CAN 通道。 Provides handling for STM32 CAN channels. More...

#include <stm32_can.hpp>

Inheritance diagram for LibXR::STM32CAN:
[legend]
Collaboration diagram for LibXR::STM32CAN:
[legend]

Public Member Functions

 STM32CAN (CAN_HandleTypeDef *hcan, uint32_t pool_size)
 STM32CAN 类,用于处理 STM32 系统的 CAN 通道。 Provides handling for STM32 CAN.
 
ErrorCode Init (void)
 初始化
 
ErrorCode AddMessage (const ClassicPack &pack) override
 添加 CAN 消息到系统 (Adds a CAN message to the system).
 
void ProcessRxInterrupt ()
 处理接收中断
 
void ProcessTxInterrupt ()
 处理发送中断
 
- Public Member Functions inherited from LibXR::CAN
 CAN ()
 构造 CAN 对象,可指定主题名称和通信域 (Constructs a CAN object with an optional topic name and domain).
 
struct __attribute__ ((packed))
 经典 CAN 消息结构 (Structure representing a classic CAN message).
 
void Register (Callback cb, Type type, FilterMode mode=FilterMode::ID_RANGE, uint32_t start_id_mask=0, uint32_t end_id_match=UINT32_MAX)
 注册回调函数 Registers a callback function
 

Data Fields

CAN_HandleTypeDef * hcan_
 
stm32_can_id_t id_
 
uint32_t fifo_
 
struct { 
 
   CAN_RxHeaderTypeDef   header 
 
   ClassicPack   pack 
 
rx_buff_ 
 
struct { 
 
   CAN_TxHeaderTypeDef   header 
 
   ClassicPack   pack 
 
tx_buff_ 
 
uint32_t txMailbox
 
LockFreePool< ClassicPack > tx_pool_
 
std::atomic< uint32_t > bus_busy_ = 0
 
- Data Fields inherited from LibXR::CAN
 ClassicPack
 

Static Public Attributes

static STM32CANmap [STM32_CAN_NUMBER] = {nullptr}
 

Additional Inherited Members

- Public Types inherited from LibXR::CAN
enum class  Type : uint8_t {
  STANDARD = 0 , EXTENDED = 1 , REMOTE_STANDARD = 2 , REMOTE_EXTENDED = 3 ,
  TYPE_NUM
}
 CAN 消息类型 (Enumeration of CAN message types). More...
 
enum class  FilterMode : uint8_t { ID_MASK = 0 , ID_RANGE = 1 }
 
using Callback = LibXR::Callback<const ClassicPack &>
 
- Protected Member Functions inherited from LibXR::CAN
void OnMessage (const ClassicPack &pack, bool in_isr)
 

Detailed Description

STM32CAN 类,用于处理 STM32 系统的 CAN 通道。 Provides handling for STM32 CAN channels.

Definition at line 38 of file stm32_can.hpp.

Constructor & Destructor Documentation

◆ STM32CAN()

STM32CAN::STM32CAN ( CAN_HandleTypeDef * hcan,
uint32_t pool_size )

STM32CAN 类,用于处理 STM32 系统的 CAN 通道。 Provides handling for STM32 CAN.

Parameters
hcanSTM32CAN对象 CAN object
pool_size发送池大小 Send pool size

Definition at line 47 of file stm32_can.cpp.

48 : CAN(), hcan_(hcan), id_(STM32_CAN_GetID(hcan->Instance)), tx_pool_(pool_size)
49{
50 map[id_] = this;
51 Init();
52}
CAN()
构造 CAN 对象,可指定主题名称和通信域 (Constructs a CAN object with an optional topic name and domain).
Definition can.hpp:34
ErrorCode Init(void)
初始化
Definition stm32_can.cpp:54

Member Function Documentation

◆ AddMessage()

ErrorCode STM32CAN::AddMessage ( const ClassicPack & pack)
overridevirtual

添加 CAN 消息到系统 (Adds a CAN message to the system).

Parameters
pack经典 CAN 消息包 (The classic CAN message packet).
Returns
操作结果 (ErrorCode indicating success or failure).

Implements LibXR::CAN.

Definition at line 139 of file stm32_can.cpp.

140{
141 CAN_TxHeaderTypeDef txHeader; // NOLINT
142
143 txHeader.DLC = sizeof(pack.data);
144
145 switch (pack.type)
146 {
147 case Type::STANDARD:
148 txHeader.IDE = CAN_ID_STD;
149 txHeader.RTR = CAN_RTR_DATA;
150 break;
151 case Type::EXTENDED:
152 txHeader.IDE = CAN_ID_EXT;
153 txHeader.RTR = CAN_RTR_DATA;
154 break;
156 txHeader.IDE = CAN_ID_STD;
157 txHeader.RTR = CAN_RTR_REMOTE;
158 break;
160 txHeader.IDE = CAN_ID_EXT;
161 txHeader.RTR = CAN_RTR_REMOTE;
162 break;
163 default:
164 ASSERT(false);
165 return ErrorCode::FAILED;
166 }
167 txHeader.StdId = (pack.type == Type::EXTENDED) ? 0 : pack.id;
168 txHeader.ExtId = (pack.type == Type::EXTENDED) ? pack.id : 0;
169 txHeader.TransmitGlobalTime = DISABLE;
170
171 while (true)
172 {
173 uint32_t slot = 0;
174
175 if (HAL_CAN_AddTxMessage(hcan_, &txHeader, pack.data, &txMailbox) != HAL_OK)
176 {
177 if (tx_pool_.Put(pack, slot) != ErrorCode::OK)
178 {
179 return ErrorCode::FULL;
180 }
181 }
182 else
183 {
184 return ErrorCode::OK;
185 }
186
187 if (bus_busy_.load(std::memory_order_acquire) == 0 &&
188 tx_pool_.RecycleSlot(slot) == ErrorCode::OK)
189 {
190 continue;
191 }
192 else
193 {
194 return ErrorCode::OK;
195 }
196 }
197}
@ EXTENDED
扩展 CAN 消息 (Extended CAN message).
@ REMOTE_EXTENDED
远程扩展 CAN 消息 (Remote extended CAN message).
@ STANDARD
标准 CAN 消息 (Standard CAN message).
@ REMOTE_STANDARD
远程标准 CAN 消息 (Remote standard CAN message).
ErrorCode RecycleSlot(uint32_t index)
回收指定槽位 / Recycle a slot
ErrorCode Put(const Data &data)
向池中放入一个元素 / Put an element into the pool

◆ Init()

ErrorCode STM32CAN::Init ( void )

初始化

Returns
ErrorCode

Definition at line 54 of file stm32_can.cpp.

55{
56 CAN_FilterTypeDef can_filter = {};
57
58 can_filter.FilterIdHigh = 0;
59 can_filter.FilterIdLow = 0;
60 can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
61 can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
62 can_filter.FilterMaskIdHigh = 0;
63 can_filter.FilterMaskIdLow = 0;
64 can_filter.FilterFIFOAssignment = fifo_;
65 can_filter.FilterActivation = ENABLE;
66#ifdef CAN3
67 if (id_ == STM32_CAN1)
68 {
69 can_filter.FilterBank = 0;
70 can_filter.SlaveStartFilterBank = 14;
71 fifo_ = CAN_RX_FIFO0;
72 }
73 else if (id_ == STM32_CAN2)
74 {
75 can_filter.FilterBank = 14;
76 can_filter.SlaveStartFilterBank = 14;
77 fifo_ = CAN_RX_FIFO0;
78 }
79 else if (id_ == STM32_CAN3)
80 {
81 can_filter.FilterBank = 3;
82 fifo_ = CAN_RX_FIFO1;
83 }
84#else
85#ifdef CAN2
86 if (id_ == STM32_CAN1)
87 {
88 can_filter.FilterBank = 0;
89 can_filter.SlaveStartFilterBank = 14;
90 fifo_ = CAN_RX_FIFO0;
91 }
92 else if (id_ == STM32_CAN2)
93 {
94 can_filter.FilterBank = 14;
95 can_filter.SlaveStartFilterBank = 14;
96 fifo_ = CAN_RX_FIFO1;
97 }
98#else
99 if (id_ == STM32_CAN1)
100 {
101 can_filter.FilterBank = 0;
102 can_filter.SlaveStartFilterBank = 14;
103 fifo_ = CAN_RX_FIFO0;
104 }
105#endif
106#endif
107 else
108 {
109 ASSERT(false);
110 return ErrorCode::FAILED;
111 }
112 can_filter.FilterFIFOAssignment = fifo_;
113
114 if (HAL_CAN_ConfigFilter(hcan_, &can_filter) != HAL_OK)
115 {
116 return ErrorCode::FAILED;
117 }
118
119 if (HAL_CAN_Start(hcan_) != HAL_OK)
120 {
121 return ErrorCode::FAILED;
122 }
123
124 if (fifo_ == CAN_RX_FIFO0)
125 {
126 HAL_CAN_ActivateNotification(hcan_, CAN_IT_RX_FIFO0_MSG_PENDING);
127 }
128 else
129 {
130 HAL_CAN_ActivateNotification(hcan_, CAN_IT_RX_FIFO1_MSG_PENDING);
131 }
132
133 HAL_CAN_ActivateNotification(hcan_, CAN_IT_ERROR);
134 HAL_CAN_ActivateNotification(hcan_, CAN_IT_TX_MAILBOX_EMPTY);
135
136 return ErrorCode::OK;
137}

◆ ProcessRxInterrupt()

void STM32CAN::ProcessRxInterrupt ( )

处理接收中断

Definition at line 199 of file stm32_can.cpp.

200{
201 while (HAL_CAN_GetRxMessage(hcan_, fifo_, &rx_buff_.header, rx_buff_.pack.data) ==
202 HAL_OK)
203 {
204 if (rx_buff_.header.IDE == CAN_ID_STD)
205 {
206 if (rx_buff_.header.StdId == 2046)
207 {
208 __NOP();
209 }
210 rx_buff_.pack.id = rx_buff_.header.StdId;
211 rx_buff_.pack.type = Type::STANDARD;
212 }
213 else
214 {
215 rx_buff_.pack.id = rx_buff_.header.ExtId;
216 rx_buff_.pack.type = Type::EXTENDED;
217 }
218
219 if (rx_buff_.header.RTR == CAN_RTR_REMOTE)
220 {
221 if (rx_buff_.pack.type == Type::STANDARD)
222 {
223 rx_buff_.pack.type = Type::REMOTE_STANDARD;
224 }
225 else
226 {
227 rx_buff_.pack.type = Type::REMOTE_EXTENDED;
228 }
229 }
230 OnMessage(rx_buff_.pack, true);
231 }
232}

◆ ProcessTxInterrupt()

void STM32CAN::ProcessTxInterrupt ( )

处理发送中断

Definition at line 234 of file stm32_can.cpp.

235{
236 if (tx_pool_.Get(tx_buff_.pack) == ErrorCode::OK)
237 {
238 tx_buff_.header.DLC = sizeof(tx_buff_.pack.data);
239 switch (tx_buff_.pack.type)
240 {
241 case Type::STANDARD:
242 tx_buff_.header.IDE = CAN_ID_STD;
243 tx_buff_.header.RTR = CAN_RTR_DATA;
244 break;
245 case Type::EXTENDED:
246 tx_buff_.header.IDE = CAN_ID_EXT;
247 tx_buff_.header.RTR = CAN_RTR_DATA;
248 break;
250 tx_buff_.header.IDE = CAN_ID_STD;
251 tx_buff_.header.RTR = CAN_RTR_REMOTE;
252 break;
254 tx_buff_.header.IDE = CAN_ID_EXT;
255 tx_buff_.header.RTR = CAN_RTR_REMOTE;
256 break;
257 default:
258 ASSERT(false);
259 return;
260 }
261 tx_buff_.header.StdId = (tx_buff_.pack.type == Type::EXTENDED) ? 0 : tx_buff_.pack.id;
262 tx_buff_.header.ExtId = (tx_buff_.pack.type == Type::EXTENDED) ? tx_buff_.pack.id : 0;
263 tx_buff_.header.TransmitGlobalTime = DISABLE;
264
265 HAL_CAN_AddTxMessage(hcan_, &tx_buff_.header, tx_buff_.pack.data, &txMailbox);
266
267 bus_busy_.store(UINT32_MAX, std::memory_order_release);
268 }
269 else
270 {
271 uint32_t tsr = READ_REG(hcan_->Instance->TSR);
272
273 if (((tsr & CAN_TSR_TME0) != 0U) && ((tsr & CAN_TSR_TME1) != 0U) &&
274 ((tsr & CAN_TSR_TME2) != 0U))
275 {
276 bus_busy_.store(0, std::memory_order_release);
277 }
278 else
279 {
280 bus_busy_.store(UINT32_MAX, std::memory_order_release);
281 }
282 }
283}
ErrorCode Get(Data &data)
从池中取出一个元素 / Retrieve an element from the pool

Field Documentation

◆ bus_busy_

std::atomic<uint32_t> LibXR::STM32CAN::bus_busy_ = 0

Definition at line 92 of file stm32_can.hpp.

◆ fifo_

uint32_t LibXR::STM32CAN::fifo_

Definition at line 73 of file stm32_can.hpp.

◆ hcan_

CAN_HandleTypeDef* LibXR::STM32CAN::hcan_

Definition at line 70 of file stm32_can.hpp.

◆ header [1/2]

CAN_RxHeaderTypeDef LibXR::STM32CAN::header

Definition at line 78 of file stm32_can.hpp.

◆ header [2/2]

CAN_TxHeaderTypeDef LibXR::STM32CAN::header

Definition at line 84 of file stm32_can.hpp.

◆ id_

stm32_can_id_t LibXR::STM32CAN::id_

Definition at line 72 of file stm32_can.hpp.

◆ map

STM32CAN * STM32CAN::map = {nullptr}
static

Definition at line 74 of file stm32_can.hpp.

◆ pack

ClassicPack LibXR::STM32CAN::pack

Definition at line 79 of file stm32_can.hpp.

◆ tx_pool_

LockFreePool<ClassicPack> LibXR::STM32CAN::tx_pool_

Definition at line 90 of file stm32_can.hpp.

◆ txMailbox

uint32_t LibXR::STM32CAN::txMailbox

Definition at line 88 of file stm32_can.hpp.


The documentation for this class was generated from the following files: