Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (4.82 KB)

1
/*
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
#include <aos_thread.h>
24
#include <chthreads.h>
25
#include <chtime.h>
26
#include <ch.h>
27
#include <stdbool.h>
28
#define True 1
29
#define False 0
30
#define HRTMSG 00
31
#define SRTMSG 01
32
#define NRTMSG 11
33
#define SLEEPTIME 20
34

    
35
static THD_WORKING_AREA(myThreadWorkingArea, 128);
36

    
37
msgqueue_t hrtQueue;
38
msgqueue_t srtQueue;
39
msgqueue_t nrtQueue;
40

    
41
/*
42
 * @brief transmit Message over CAN
43
 */
44
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
/*
52
 * @brief receive Message over CAN
53
 */
54
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
bool pushRTCanMsgSorted(rtcan_msg_t *msg,msgqueue_t* msgqueue){
60

    
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
            msgqueue->size++;
72
            return true;
73
        }
74
    }
75
    if(compareElem!= NULL){
76
      msg->next = compareElem;
77
    }
78
    return false;
79
}
80

    
81
/*
82
 * @brief push Message to its Queue, based on type of Message
83
 */
84
bool pushRTCanMsg(rtcan_msg_t *msg,msgqueue_t* msgqueue){
85
  if(msg != NULL){
86
    if(msgqueueEmpty(msgqueue)){
87
        queueInit(msg,msgqueue);
88
        return true;
89
    }
90
      msgqueue->tail->next = msg;
91
      msg->next = NULL;
92
      msgqueue->tail = msg;
93
      msgqueue->size++;
94
      return true;
95
    }
96
  return false;
97
}
98

    
99
/*
100
 * @brief dequeue Message from Queue
101
 */
102
rtcan_msg_t* popRTCanMsg(msgqueue_t* msgqueue){
103
    //todo special case head = tail
104
  if(!msgqueueEmpty(msgqueue)){
105
      rtcan_msg_t *elem = msgqueue->head;
106
      msgqueue->head = elem->next;
107
      msgqueue->size--;
108
      return elem;
109
  }
110
  return NULL;
111
}
112

    
113
/*
114
 * @brief init Message Queue
115
 */
116
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
}
123

    
124
// Handling Message Queues
125

    
126
bool enqueueMsg(uint8_t *payload, uint8_t msgType, aos_timestamp_t deadline){
127
  static rtcan_msg_t msg;
128
  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
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

    
155
/**
156
 * @brief schedule rtcan messages into mailboxes
157
 */
158

    
159
static msg_t Thread(void *arg){
160
  (void)arg;
161
  chRegSetThreadName("RTCAN Timer");
162
  int nextSlot; // set by while loop from calendar
163

    
164
  while (true){
165
    // send Frame of Timeslot
166
    // iterate over calendar(bitmask)
167
    rtcan_msg_t *nextMsg;
168
    chThdSleepMilliseconds( SLEEPTIME );
169
    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
    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
  }
186

    
187
  return 0;
188
}
189
/** empty or clear?*/
190
int msgqueueEmpty(msgqueue_t* mqueue){
191
    if(mqueue == NULL){
192
        return true;
193
    }
194
    return false;
195
}
196
//TODO: ISR
197
//TODO: Params