Statistics
| Branch: | Tag: | Revision:

amiro-os / core / src / aos_rtcan.c @ 341cc329

History | View | Annotate | Download (4.82 KB)

1 d2931db9 Julian L
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
4

5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <hal.h>
20
#include <hal_can.h>
21
#include <hal_can_lld.h>
22
#include <aos_rtcan.h>
23 e7131d09 Julian Leichert
#include <aos_thread.h>
24
#include <chthreads.h>
25 ece66d59 Julian Leichert
#include <chtime.h>
26
#include <ch.h>
27 7f37b11b Julian Leichert
#include <stdbool.h>
28 d2931db9 Julian L
#define True 1
29
#define False 0
30 7f37b11b Julian Leichert
#define HRTMSG 00
31
#define SRTMSG 01
32
#define NRTMSG 11
33 341cc329 Julian Leichert
#define SLEEPTIME 20
34 d2931db9 Julian L
35 ece66d59 Julian Leichert
static THD_WORKING_AREA(myThreadWorkingArea, 128);
36
37
msgqueue_t hrtQueue;
38
msgqueue_t srtQueue;
39
msgqueue_t nrtQueue;
40
41 e7131d09 Julian Leichert
/*
42
 * @brief transmit Message over CAN
43
 */
44 d2931db9 Julian L
msg_t rtcan_transmit(CANDriver *canp, canmbx_t mailbox, const CANTxFrame *ctfp){
45
    // call cantransmit, needed params driver, mailbox and tx frame
46
47
    msg_t transmit = canTransmitTimeout(canp,mailbox,ctfp,TIME_IMMEDIATE);
48
    return transmit;
49
}
50
51 e7131d09 Julian Leichert
/*
52
 * @brief receive Message over CAN
53
 */
54 d2931db9 Julian L
msg_t rtcan_receive(CANDriver *canp, canmbx_t mailbox,CANRxFrame *crfp){
55
    // call lld cantransmit, needed params driver, mailbox and rx frame
56
    return canReceiveTimeout(canp,mailbox,crfp,TIME_IMMEDIATE);
57
}
58
59 e7131d09 Julian Leichert
bool pushRTCanMsgSorted(rtcan_msg_t *msg,msgqueue_t* msgqueue){
60 ece66d59 Julian Leichert
61
    rtcan_msg_t * prevElem = msgqueue->head;
62
    rtcan_msg_t * compareElem = prevElem->next;
63
64
    while(ST2MS(msg->deadline) >= ST2MS(compareElem->deadline)){
65
        if(compareElem->next != NULL){
66
            prevElem = compareElem;
67
            compareElem = compareElem->next;
68
        }else{
69
            prevElem->next = msg;
70
            msgqueue->tail = msg;
71 341cc329 Julian Leichert
            msgqueue->size++;
72 ece66d59 Julian Leichert
            return true;
73
        }
74
    }
75
    if(compareElem!= NULL){
76
      msg->next = compareElem;
77
    }
78 e7131d09 Julian Leichert
    return false;
79 d2931db9 Julian L
}
80
81 e7131d09 Julian Leichert
/*
82
 * @brief push Message to its Queue, based on type of Message
83
 */
84 7f37b11b Julian Leichert
bool pushRTCanMsg(rtcan_msg_t *msg,msgqueue_t* msgqueue){
85 e7131d09 Julian Leichert
  if(msg != NULL){
86
    if(msgqueueEmpty(msgqueue)){
87 b85b6b26 Julian Leichert
        queueInit(msg,msgqueue);
88 7f37b11b Julian Leichert
        return true;
89 e7131d09 Julian Leichert
    }
90
      msgqueue->tail->next = msg;
91 5766017b Julian Leichert
      msg->next = NULL;
92 e7131d09 Julian Leichert
      msgqueue->tail = msg;
93
      msgqueue->size++;
94 7f37b11b Julian Leichert
      return true;
95 d2931db9 Julian L
    }
96 7f37b11b Julian Leichert
  return false;
97 d2931db9 Julian L
}
98
99 e7131d09 Julian Leichert
/*
100
 * @brief dequeue Message from Queue
101
 */
102
rtcan_msg_t* popRTCanMsg(msgqueue_t* msgqueue){
103 7f37b11b Julian Leichert
    //todo special case head = tail
104 ece66d59 Julian Leichert
  if(!msgqueueEmpty(msgqueue)){
105
      rtcan_msg_t *elem = msgqueue->head;
106
      msgqueue->head = elem->next;
107 341cc329 Julian Leichert
      msgqueue->size--;
108 ece66d59 Julian Leichert
      return elem;
109
  }
110
  return NULL;
111
}
112
113
/*
114
 * @brief init Message Queue
115
 */
116 b85b6b26 Julian Leichert
void queueInit(rtcan_msg_t *head,msgqueue_t* msgqueue){
117
  msgqueue->size = 0;
118
  msgqueue->head = head;
119
  msgqueue->tail = head;
120
  head->next = NULL;
121
  msgqueue->size++;
122 d2931db9 Julian L
}
123
124 7f37b11b Julian Leichert
// Handling Message Queues
125
126 341cc329 Julian Leichert
bool enqueueMsg(uint8_t *payload, uint8_t msgType, aos_timestamp_t deadline){
127 6d56ad8d Julian Leichert
  static rtcan_msg_t msg;
128 7f37b11b Julian Leichert
  msg.payload = payload;
129
  msg.msgType = msgType;
130
  msg.deadline = deadline;
131
  if(msgType == HRTMSG){
132
    return pushRTCanMsg(&msg,&hrtQueue);
133
  }else if(msgType == SRTMSG){
134
    return pushRTCanMsgSorted(&msg,&srtQueue);
135
  }else if(msgType == NRTMSG){
136
    return pushRTCanMsg(&msg,&nrtQueue);
137
  }
138
  return false;
139
}
140
141 341cc329 Julian Leichert
u_int32_t createId(rtcan_msg_t *msg, uint8_t msgType){
142
    // first 6 bit laxity
143
    // 6-21 id
144
    // 21-29 fragment
145
    u_int32_t id = 0;
146
    aos_timestamp_t uptime;
147
    aosSysGetUptime(&uptime);
148
149
   uint32_t uptimeMcs = (uint32_t)(uptime / MICROSECONDS_PER_DAY);
150
151
152
}
153
154 7f37b11b Julian Leichert
155 e7131d09 Julian Leichert
/**
156
 * @brief schedule rtcan messages into mailboxes
157
 */
158 d2931db9 Julian L
159 ece66d59 Julian Leichert
static msg_t Thread(void *arg){
160
  (void)arg;
161
  chRegSetThreadName("RTCAN Timer");
162 2538f3de Julian Leichert
  int nextSlot; // set by while loop from calendar
163 ece66d59 Julian Leichert
164 7f37b11b Julian Leichert
  while (true){
165 341cc329 Julian Leichert
    // send Frame of Timeslot
166 2538f3de Julian Leichert
    // iterate over calendar(bitmask)
167
    rtcan_msg_t *nextMsg;
168 341cc329 Julian Leichert
    chThdSleepMilliseconds( SLEEPTIME );
169 2538f3de Julian Leichert
    if(nextSlot == 1){
170
      nextMsg = popRTCanMsg(&hrtQueue);
171
    }else{
172
      if(!msgqueueEmpty(srtQueue)){
173
        nextMsg = popRTCanMsg(&srtQueue);
174
      }else{
175
        nextMsg = popRTCanMsg(&nrtQueue);
176
      }
177
    }
178 341cc329 Julian Leichert
    if(nextMsg != NULL){
179
      // create frame
180
      // frame needs id, payload(later) and ___
181
      // place it in Mailbox to be sent in next time slot
182
    }
183
     // maybe send empty message if no message to reduce jitter????
184
    chThdSleepMilliseconds( SLEEPTIME );
185 ece66d59 Julian Leichert
  }
186 d2931db9 Julian L
187 ece66d59 Julian Leichert
  return 0;
188
}
189 d2931db9 Julian L
/** empty or clear?*/
190
int msgqueueEmpty(msgqueue_t* mqueue){
191
    if(mqueue == NULL){
192 7f37b11b Julian Leichert
        return true;
193 d2931db9 Julian L
    }
194 7f37b11b Julian Leichert
    return false;
195 d2931db9 Julian L
}
196
//TODO: ISR
197
//TODO: Params