can_message.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include "bsp/bsp.h"
  2. #include "os/co_task.h"
  3. #include "libs/logger.h"
  4. #include "libs/utils.h"
  5. #include "can_message.h"
  6. #include "wait_queue.h"
  7. #define MAX_CAN_MESSAGE 4
  8. static can_message_t messages[MAX_CAN_MESSAGE];
  9. static msg_list_t msg_list[10];
  10. static wait_queue_t wait_queue;
  11. static node_list_t _pending_list = LIST_HEAD_INIT(_pending_list);
  12. static node_list_t _idle_list = LIST_HEAD_INIT(_idle_list);
  13. static void can_process_message(can_message_t *message);
  14. static void free_can_message(can_message_t *message);
  15. static void _can_poll_task(void*);
  16. static void handle_can_frame(void);
  17. void can_message_init(void){
  18. for(int i = 0; i < ARRAY_SIZE(msg_list); i++) {
  19. init_list_node(&msg_list[i].list);
  20. list_add_tail(&_idle_list, &msg_list[i].list);
  21. }
  22. shark_can0_init();
  23. co_task_create(_can_poll_task, NULL, 256);
  24. }
  25. void put_raw_message(can_id_t id, uint8_t *data, int len) {
  26. if (list_empty(&_idle_list)){
  27. return;
  28. }
  29. msg_list_t *raw = (msg_list_t *)_idle_list.next;
  30. list_del(&raw->list);
  31. raw->msg.id = id;
  32. raw->msg.len = len;
  33. memcpy(raw->msg.data, data, len);
  34. list_add_tail(&_pending_list, &raw->list);
  35. }
  36. static msg_list_t *_get_raw_message(void) {
  37. if (list_empty(&_pending_list)){
  38. return NULL;
  39. }
  40. msg_list_t *raw = (msg_list_t *)_pending_list.next;
  41. list_del(&raw->list);
  42. return raw;
  43. }
  44. static void free_raw_message(msg_list_t *raw) {
  45. list_add_tail(&_idle_list, &raw->list);
  46. }
  47. static void _can_poll_task(void *args) {
  48. while(1) {
  49. handle_can_frame();
  50. co_task_yield();
  51. }
  52. }
  53. static can_message_t *get_message_by_id(can_id_t id){
  54. can_message_t *idle_msg = NULL;
  55. can_message_t *src_msg = NULL;
  56. for (int i = 0; i < MAX_CAN_MESSAGE; i++){
  57. /*first found the same src&dest */
  58. if ((messages[i].src == id.src) && (messages[i].dest == id.dest)){
  59. return (messages + i);
  60. }
  61. if (messages[i].src == id.src){
  62. src_msg = messages + i;
  63. }else if (messages[i].data == NULL){
  64. idle_msg = messages + i;
  65. }
  66. }
  67. return ((src_msg!=NULL)?src_msg:idle_msg);
  68. }
  69. s32 can_send_message(uint32_t can_id, u8 *data, int len, s32 timeout){
  70. can_id_t id;
  71. id.id = can_id;
  72. if (id.type != ptype_request || id.retry <= 1) {
  73. return shark_can0_send_message(can_id, data, len) == 0?CAN_SEND_SUCCESS:CAN_SEND_ERROR;
  74. }
  75. s32 s_ret = CAN_SEND_NO_WAIT_QUEUE;
  76. s32 index = wait_queue_add(&wait_queue, decoder_can_key(data));
  77. if (index >= 0){
  78. s_ret = CAN_SEND_TIMEOUT;
  79. s32 retry = id.retry;
  80. while(retry -- > 0) {
  81. s_ret = shark_can0_send_message(can_id, data, len) == 0?CAN_SEND_SUCCESS:CAN_SEND_ERROR;
  82. if (s_ret != CAN_SEND_SUCCESS){
  83. continue;
  84. }
  85. s_ret = wait_queue_wait_key(&wait_queue, index, timeout)?CAN_SEND_SUCCESS:CAN_SEND_TIMEOUT;
  86. if (s_ret == CAN_SEND_SUCCESS){
  87. break;
  88. }
  89. }
  90. wait_queue_delete_key(&wait_queue, index);
  91. }
  92. return s_ret;
  93. }
  94. static void handle_can_frame(void){
  95. msg_list_t *raw = _get_raw_message();
  96. if (raw == NULL) {
  97. return;
  98. }
  99. can_id_t id = raw->msg.id;
  100. uint8_t *data = raw->msg.data;
  101. int len = raw->msg.len;
  102. can_message_t *message = get_message_by_id(id);
  103. if (message == NULL) {
  104. return ;
  105. }
  106. uint16_t key = 0;
  107. int total = id.total?id.total:32;
  108. int idx = id.idx?id.idx:32;
  109. if((total <= CAN_MESSAGE_MAX_FRAMES) && (idx <= CAN_MESSAGE_MAX_FRAMES)
  110. && (idx <= total)){
  111. if ((idx == 1) && (len >= 2)) { //first frame for message
  112. key = decoder_can_key(data);
  113. message->key = key;
  114. message->dest = id.dest;
  115. message->src = id.src;
  116. message->len = 0;
  117. message->idx = idx;
  118. message->type= id.type;
  119. message->total_frame = total;
  120. len = len - 2; //skip key
  121. data = data + 2;
  122. }
  123. if (message->data){
  124. if ((message->idx == idx) && (message->total_frame == total)){
  125. memcpy(message->data + message->len, data, len);
  126. message->len += len;
  127. if (idx == total) { //last frame
  128. if (id.type == ptype_response) {
  129. wait_queue_key_acked(&wait_queue, message->key);
  130. }
  131. can_process_message(message);
  132. }
  133. message->idx = (idx + 1);
  134. }else {
  135. free_can_message(message);
  136. }
  137. }
  138. }
  139. free_raw_message(raw);
  140. }
  141. static void can_process_message(can_message_t *message){
  142. if (message->key & 0xFF >= 0xF0) {
  143. //do iap update
  144. }else if (message->src == 0x42){ //只处理后控的指令
  145. }
  146. free_can_message(message);
  147. }
  148. static void free_can_message(can_message_t *message){
  149. message->src = 0;
  150. message->len = 0;
  151. message->idx = 0xFF;
  152. message->total_frame = 0xFF;
  153. }
  154. void can_send_response(uint8_t can_add, uint8_t *data, int len){
  155. can_send_message(get_reponse_can_id(can_add), data, len, 50);
  156. }
  157. void can_send_message_ack(can_message_t *msg, uint8_t success){
  158. u8 response[3];
  159. encoder_can_key(response, msg->key);
  160. response[2] = success;
  161. can_send_message(get_reponse_can_id(msg->src), response, 3, 50);
  162. }
  163. void can_send_indicator(uint8_t can_add, uint8_t *data, int len){
  164. can_send_message(get_indicator_can_id(can_add), data, len, 50);
  165. }
  166. void can_send_request(uint8_t can_add, uint8_t *data, int len){
  167. can_send_message(get_request_can_id(can_add,3), data, len, 300);
  168. }