基质喷涂
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

298 lines
8.5 KiB

  1. #include "can_controller.h"
  2. #include <cstring>
  3. #include <main.h>
  4. #include <base/zlog.h>
  5. #define TAG "CAN"
  6. #define CAN_MESSAGE_POOL_SIZE 20
  7. // 使用 CMSIS - RTOS v2 的内存池句柄类型
  8. osMemoryPoolId_t can_message_pool;
  9. // 使用 CMSIS - RTOS v2 的信号量句柄类型
  10. osSemaphoreId_t g_can_rx0_semaphore = NULL;
  11. // 使用 CMSIS - RTOS v2 的消息队列句柄类型
  12. osMessageQueueId_t g_can_rx0_queue = NULL;
  13. CanMessage g_can_recv_msg;
  14. CANSystemResourceManager canSystemResourceManager;
  15. // 新的线程函数
  16. void canMessageProcessingTask(void *argument) {
  17. while (1) {
  18. // 等待信号量
  19. osSemaphoreAcquire(g_can_rx0_semaphore, osWaitForever);
  20. CanMessage* msgPtr = (CanMessage*)osMemoryPoolAlloc(can_message_pool, osWaitForever);
  21. if (msgPtr == NULL) {
  22. continue;
  23. }
  24. msgPtr->id = g_can_recv_msg.id;
  25. msgPtr->length = g_can_recv_msg.length;
  26. memcpy(msgPtr->data, g_can_recv_msg.data, msgPtr->length);
  27. #if 1
  28. // 将消息放入接收队列
  29. osStatus_t status = osMessageQueuePut(g_can_rx0_queue, &msgPtr, 0U, 0U);
  30. if (status != osOK) {
  31. osMemoryPoolFree(can_message_pool, msgPtr);
  32. }
  33. #endif
  34. }
  35. }
  36. CANSystemResourceManager::CANSystemResourceManager() {
  37. // 初始化信号量
  38. osSemaphoreAttr_t semaphore_attr = {0};
  39. semaphore_attr.name = "g_can_rx0_semaphore";
  40. g_can_rx0_semaphore = osSemaphoreNew(1, 1, &semaphore_attr);
  41. if (g_can_rx0_semaphore == NULL) {
  42. // 处理信号量创建失败的情况
  43. }
  44. // 创建对象池
  45. osMemoryPoolAttr_t pool_attr = {0};
  46. pool_attr.name = "can_message_pool";
  47. can_message_pool = osMemoryPoolNew(CAN_MESSAGE_POOL_SIZE, sizeof(CanMessage), &pool_attr);
  48. if (can_message_pool == NULL) {
  49. // 处理对象池创建失败的情况
  50. if (g_can_rx0_semaphore != NULL) {
  51. osSemaphoreDelete(g_can_rx0_semaphore);
  52. }
  53. }
  54. // 创建接收队列
  55. osMessageQueueAttr_t queue_attr = {0};
  56. queue_attr.name = "g_can_rx0_queue";
  57. g_can_rx0_queue = osMessageQueueNew(20, sizeof(CanMessage*), &queue_attr);
  58. if (g_can_rx0_queue == NULL) {
  59. // 处理消息队列创建失败的情况
  60. if (g_can_rx0_semaphore != NULL) {
  61. osSemaphoreDelete(g_can_rx0_semaphore);
  62. }
  63. if (can_message_pool != NULL) {
  64. osMemoryPoolDelete(can_message_pool);
  65. }
  66. }
  67. // 创建 CAN 消息处理线程
  68. osThreadAttr_t canProcessingTaskAttr = {0};
  69. canProcessingTaskAttr.name = "CanMessageProcessingTask";
  70. canProcessingTaskAttr.stack_size = 128 * 8;
  71. canProcessingTaskAttr.priority = osPriorityNormal;
  72. osThreadNew(canMessageProcessingTask, NULL, &canProcessingTaskAttr);
  73. }
  74. CANSystemResourceManager::~CANSystemResourceManager() {
  75. // 释放信号量
  76. if (g_can_rx0_semaphore != NULL) {
  77. osSemaphoreDelete(g_can_rx0_semaphore);
  78. }
  79. // 释放消息队列
  80. if (g_can_rx0_queue != NULL) {
  81. osMessageQueueDelete(g_can_rx0_queue);
  82. }
  83. // 释放对象池
  84. if (can_message_pool != NULL) {
  85. osMemoryPoolDelete(can_message_pool);
  86. }
  87. }
  88. /**
  89. * @brief CAN RX0
  90. * @note CAN FIFO0的接收中断
  91. */
  92. void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
  93. if (hcan->Instance == CAN1) {
  94. CAN_RxHeaderTypeDef rx_msg_header;
  95. if (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) == 0) /* 没有接收到数据 */
  96. {
  97. return;
  98. }
  99. if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_msg_header, g_can_recv_msg.data) != HAL_OK) /* 读取数据 */
  100. {
  101. return;
  102. }
  103. #if 0
  104. if (rx_msg_header.StdId != (CAN_BASE_FRAME_ID + CAN_CONFIG->getCanFrameId()) ||
  105. rx_msg_header.IDE != CAN_ID_STD || rx_msg_header.RTR != CAN_RTR_DATA) /* 接收到的ID不对 / 不是标准帧 / 不是数据帧 */
  106. {
  107. return;
  108. }
  109. #else
  110. if ((rx_msg_header.StdId != (CAN_BASE_FRAME_ID + CAN_CONFIG->getCanFrameId()) &&
  111. rx_msg_header.StdId != (CAN_X_MOTOR_FRAME_ID + CAN_CONFIG->getCanFrameId()) &&
  112. rx_msg_header.StdId != (CAN_Y_MOTOR_FRAME_ID + CAN_CONFIG->getCanFrameId())&&
  113. rx_msg_header.StdId != (CAN_Z_MOTOR_FRAME_ID + CAN_CONFIG->getCanFrameId()))||
  114. rx_msg_header.IDE != CAN_ID_STD || rx_msg_header.RTR != CAN_RTR_DATA) /* 接收到的ID不对 / 不是标准帧 / 不是数据帧 */
  115. {
  116. return;
  117. }
  118. #endif
  119. g_can_recv_msg.id = rx_msg_header.StdId;
  120. g_can_recv_msg.length = rx_msg_header.DLC;
  121. osSemaphoreRelease(g_can_rx0_semaphore);
  122. }
  123. }
  124. CanController::CanController()
  125. : tx_queue(NULL),
  126. tx_task_handle(NULL) {
  127. }
  128. CanController::~CanController() {
  129. stop();
  130. }
  131. bool CanController::start(CAN_HandleTypeDef* hcan) {
  132. this->hcan = hcan;
  133. // 启动CAN外围设备
  134. CAN_FilterTypeDef sFilterConfig;
  135. /* 配置CAN过滤器 */
  136. sFilterConfig.FilterBank = 0; /* 过滤器0 */
  137. sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  138. sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  139. sFilterConfig.FilterIdHigh = 0x0000; /* 32位ID */
  140. sFilterConfig.FilterIdLow = 0x0000;
  141. sFilterConfig.FilterMaskIdHigh = 0x0000; /* 32位MASK */
  142. sFilterConfig.FilterMaskIdLow = 0x0000;
  143. sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; /* 过滤器0关联到FIFO0 */
  144. sFilterConfig.FilterActivation = CAN_FILTER_ENABLE; /* 激活滤波器0 */
  145. sFilterConfig.SlaveStartFilterBank = 14;
  146. /* 过滤器配置 */
  147. if (HAL_CAN_ConfigFilter(hcan, &sFilterConfig) != HAL_OK) {
  148. Error_Handler();
  149. }
  150. if (HAL_CAN_Start(hcan) != HAL_OK) {
  151. Error_Handler();
  152. }
  153. if (HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
  154. Error_Handler();
  155. }
  156. mutex_tx_queue_ = osMutexNew(NULL);
  157. // 创建发送队列
  158. osMessageQueueAttr_t tx_queue_attr = {0};
  159. tx_queue_attr.name = "tx_queue";
  160. tx_queue = osMessageQueueNew(20, sizeof(CanMessage*), &tx_queue_attr);
  161. if (tx_queue == NULL) {
  162. return false;
  163. }
  164. // 创建发送任务
  165. osThreadAttr_t tx_task_attr = {0};
  166. tx_task_attr.name = "CanTxTask";
  167. tx_task_attr.stack_size = 256 * 8;
  168. tx_task_attr.priority = osPriorityNormal;
  169. tx_task_handle = osThreadNew(canTxTask, this, &tx_task_attr);
  170. if (tx_task_handle == NULL) {
  171. return false;
  172. }
  173. // 创建协议解析任务
  174. osThreadAttr_t parser_task_attr = {0};
  175. parser_task_attr.name = "CanParserTask";
  176. parser_task_attr.stack_size = 256 * 8;
  177. parser_task_attr.priority = osPriorityNormal;
  178. parser_task_handle = osThreadNew(canParserTask, this, &parser_task_attr);
  179. if (parser_task_handle == NULL) {
  180. osThreadTerminate(tx_task_handle);
  181. return false;
  182. }
  183. return true;
  184. }
  185. void CanController::stop() {
  186. if (tx_task_handle != NULL) {
  187. osThreadTerminate(tx_task_handle);
  188. }
  189. if (parser_task_handle != NULL) {
  190. osThreadTerminate(parser_task_handle);
  191. }
  192. if (tx_queue != NULL) {
  193. osMessageQueueDelete(tx_queue);
  194. }
  195. }
  196. bool CanController::sendMessage(const CanMessage& msg) {
  197. #if CAN_MODULE_ENABLE
  198. CanMessage* msgPtr = (CanMessage*)osMemoryPoolAlloc(can_message_pool, osWaitForever);
  199. if (msgPtr == NULL) {
  200. return false;
  201. }
  202. msg.cloneTo(msgPtr);
  203. osMutexAcquire(mutex_tx_queue_, osWaitForever);
  204. osStatus_t status = osMessageQueuePut(tx_queue, &msgPtr, 0U, 0U);
  205. osMutexRelease(mutex_tx_queue_);
  206. if (status != osOK) {
  207. osMemoryPoolFree(can_message_pool, msgPtr);
  208. return false;
  209. }
  210. return true;
  211. #endif
  212. }
  213. void CanController::canTxTask(void *argument) {
  214. CanController* controller = static_cast<CanController*>(argument);
  215. CanMessage *msgPtr = NULL;
  216. CAN_TxHeaderTypeDef can_msg_header;
  217. while (1) {
  218. osStatus_t status = osMessageQueueGet(controller->tx_queue, &msgPtr, NULL, osWaitForever);
  219. if (status == osOK) {
  220. if(msgPtr == NULL)
  221. {
  222. return;
  223. }
  224. uint16_t t = 0;
  225. uint32_t TxMailbox = CAN_TX_MAILBOX0;
  226. can_msg_header.StdId = msgPtr->id;
  227. can_msg_header.ExtId = msgPtr->id;
  228. can_msg_header.IDE = CAN_ID_STD; // 标准帧
  229. can_msg_header.RTR = CAN_RTR_DATA; // 数据帧
  230. can_msg_header.DLC = msgPtr->length;
  231. if (HAL_CAN_AddTxMessage(controller->hcan, &can_msg_header, msgPtr->data, &TxMailbox) != HAL_OK) /* 发送消息 */
  232. {
  233. osMemoryPoolFree(can_message_pool, msgPtr);
  234. continue;
  235. }
  236. while (HAL_CAN_GetTxMailboxesFreeLevel(controller->hcan) != 3) /* 等待发送完成,所有邮箱为空 */
  237. {
  238. t++;
  239. if (t > 0xFFF) {
  240. HAL_CAN_AbortTxRequest(controller->hcan, TxMailbox); /* 超时,直接中止邮箱的发送请求 */
  241. break;
  242. }
  243. }
  244. osMemoryPoolFree(can_message_pool, msgPtr);
  245. osDelay(2);
  246. }
  247. }
  248. }
  249. void CanController::canParserTask(void *argument) {
  250. #if 1
  251. CanController* controller = static_cast<CanController*>(argument);
  252. CanMessage *msgPtr = NULL;
  253. while (1) {
  254. osStatus_t status = osMessageQueueGet(g_can_rx0_queue, &msgPtr, NULL, osWaitForever);
  255. if (status == osOK) {
  256. if(msgPtr != NULL) {
  257. controller->parser.parseMessage(msgPtr);
  258. osMemoryPoolFree(can_message_pool, msgPtr);
  259. }
  260. }
  261. }
  262. #endif
  263. }