can_message.c 4.0 KB

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