Callisto4Bootloader: ARK/platform_main_freertos.c Source File

Callisto4Bootloader

platform_main_freertos.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdarg.h>
3
4 #include <arpa/inet.h> /* for ntohl() */
5
6 #include "cJSON.h"
7
8 #include "FreeRTOS.h"
9 #include "fsl_gpio.h"
10 #include "task.h"
11
12 #include "platform-api.h"
13 #include "platform-memory-map.h"
14
15 #include "platform_coap.h"
16
17 #include "httpserver-netconn.h"
18
19 // ---------------------------------------------------------------------------
20 // ---------------------------------------------------------------------------
21
22 // Value to convert stacksize in bytes into its FreeRTOS equivalent value
23 #define STACKDEPTH_IN_BYTES 4U // Assumes each stack element is 32 bits
24
25 // ---------------------------------------------------------------------------
26 // ---------------------------------------------------------------------------
27
28 // Converts abstract plugin task priorities into FreeRTOS task priority levels
29 static const UBaseType_t auxPriorityTable[ ePLATFORM_TaskPriority_MAX ] =
30 {
31 6U, // ePLATFORM_TaskPriority_Low
32 7U, // ePLATFORM_TaskPriority_Medium
33 8U, // ePLATFORM_TaskPriority_High
34 12U // ePLATFORM_TaskPriority_RealTime
35 };
36
37 // Converts abstract pin
38 static const UBaseType_t auxInterruptModeTable[ ePLATFORM_Int_MAX ] =
39 {
40 kGPIO_NoIntmode, // ePLATFORM_NoIntmode
41 kGPIO_IntLowLevel, // ePLATFORM_IntLowLevel
42 kGPIO_IntHighLevel, // ePLATFORM_IntHighLevel
43 kGPIO_IntRisingEdge, // ePLATFORM_IntRisingEdge
44 kGPIO_IntFallingEdge, // ePLATFORM_IntFallingEdge
45 kGPIO_IntRisingOrFallingEdge // ePLATFORM_IntRisingOrFallingEdge
46 };
47
48 // ---------------------------------------------------------------------------
49 // ---------------------------------------------------------------------------
50
51 // Keep a copy of all the plugins' task handles so that we can check the
52 // real-time health status of each plugin's tasks
53 static TaskHandle_t ahTaskHandles[ PLUGINS_MAX ][ ePLATFORM_TaskSlot_MAX ];
54
55 // ---------------------------------------------------------------------------
56 // ---------------------------------------------------------------------------
57
58 static GPIO_Type * const GPIOBaseArray[] =
59 {
60 GPIO1,
61 GPIO2,
62 GPIO3,
63 GPIO4
64 };
65
66 #define NUM_SUPPORTED_PORTS NUM_ELEMENTS(GPIOBaseArray)
67
68 // ---------------------------------------------------------------------------
69 // ---------------------------------------------------------------------------
70
71 // ---------------------------------------------------------------------------
72 // LOCAL FUNCTIONS
73 // ---------------------------------------------------------------------------
74
84 static inline uint32_t GPIO_PinsRead(GPIO_Type *base, uint32_t uiPin, uint32_t uiPinMask)
85 {
86 return (base->DR >> uiPin) & uiPinMask;
87 }
88
98 static inline void GPIO_PinsWrite(GPIO_Type *base, uint32_t uiPin, uint32_t uiPinMask, uint32_t uiNewValue)
99 {
100 // Should this be a task critical section?!?
101 uint32_t uiValue = base->DR;
102 uiValue &= ~(uiPinMask << uiPin);
103 uiValue |= (uiNewValue & uiPinMask) << uiPin;
104 base->DR = uiValue;
105 // Should this be a task critical section?!?
106 }
107
108 // ---------------------------------------------------------------------------
109 // ---------------------------------------------------------------------------
110
119 static bool sGetTimestamp( stPLATFORM_Timestamp_t * pstTimestamp )
120 {
121 TickType_t tickVal;
122 uint32_t ms;
123
124 tickVal = xTaskGetTickCount();
125
126 ms = tickVal * portTICK_PERIOD_MS;
127
128 pstTimestamp->uiSecs = (uint64_t)(ms / 1000U);
129 pstTimestamp->uiNanosecs = (uint32_t)((ms % 1000U) * 1000000U);
130
131 return true; // => "Code grabbed timestamp just fine"
132 }
133
148 static bool sTaskCreate(
149 uint32_t uiPluginIndex,
150 ePLATFORM_TaskSlot_t eTaskSlot,
151 void (*pvTaskCode)(void * pvParams),
152 const char * const pcTaskName,
153 void * pvParams,
154 uint32_t uiStackSizeInBytes,
155 ePLATFORM_TaskPriority_t ePriority )
156 {
157 BaseType_t xRetVal;
158 TaskHandle_t hTaskHandle;
159
160 assert(uiPluginIndex < PLUGINS_MAX);
161 assert(eTaskSlot < ePLATFORM_TaskSlot_MAX);
162
163 xRetVal = xTaskCreate( (TaskFunction_t) pvTaskCode,
164 pcTaskName,
165 (configSTACK_DEPTH_TYPE) (uiStackSizeInBytes / STACKDEPTH_IN_BYTES),
166 pvParams,
167 auxPriorityTable[ ePriority ],
168 &hTaskHandle );
169 if (xRetVal != pdPASS)
170 {
171 return false;
172 }
173 else
174 {
175 ahTaskHandles[uiPluginIndex][eTaskSlot] = hTaskHandle;
176 return true;
177 }
178 }
179
184 static void sTaskSleep( uint32_t uiMsec )
185 {
186 vTaskDelay( (TickType_t) uiMsec );
187 }
188
195 static volatile uint32_t sTaskGetTickCount( void )
196 {
197 return (uint32_t)(xTaskGetTickCount());
198 }
199
207 static void sGPIO_PinInit( uint32_t uiPin,
208 const stPLATFORM_pin_config_t * pstConfig )
209 {
210 gpio_pin_config_t stRawConfig;
211 uint32_t uiPort = uiPin / 32U;
212 uiPin &= 31U;
213
214 assert(uiPort < NUM_SUPPORTED_PORTS);
215 assert(pstConfig->direction < ePLATFORM_Digital_MAX);
216 assert(pstConfig->interruptMode < ePLATFORM_Int_MAX);
217
218 stRawConfig.direction = (gpio_pin_direction_t) pstConfig->direction;
219 stRawConfig.outputLogic = (uint8_t) pstConfig->outputLogic;
220 stRawConfig.interruptMode = (gpio_interrupt_mode_t) pstConfig->interruptMode;
221 GPIO_PinInit(GPIOBaseArray[uiPort], uiPin, &stRawConfig);
222 }
223
231 static uint8_t sGPIO_PinReadPadStatus( uint32_t uiPin )
232 {
233 uint32_t uiPort = uiPin / 32U;
234
235 assert(uiPort < NUM_SUPPORTED_PORTS); // Must map to a port
236
237 return GPIO_PinReadPadStatus(GPIOBaseArray[uiPort], uiPin & 31U);
238 }
239
247 static void sGPIO_PinSetInterruptConfig( uint32_t uiPin,
248 ePLATFORM_interrupt_mode_t pinInterruptMode )
249 {
250 uint32_t uiPort = uiPin / 32U;
251
252 assert(uiPort < NUM_SUPPORTED_PORTS); // Must map to a port
253 assert(pinInterruptMode < ePLATFORM_Int_MAX);
254
255 GPIO_PinSetInterruptConfig( GPIOBaseArray[uiPort], uiPin & 31U, auxInterruptModeTable[ pinInterruptMode ] );
256 }
257
266 static uint32_t sGPIO_PinRead( uint32_t uiPin )
267 {
268 uint32_t uiPort = uiPin / 32U;
269
270 assert(uiPort < NUM_SUPPORTED_PORTS); // Must map to a port
271
272 return GPIO_PinRead(GPIOBaseArray[uiPort], uiPin & 31U);
273 }
274
283 static uint32_t sGPIO_PinsRead( uint32_t uiPin, uint32_t uiNumPins )
284 {
285 uint32_t uiPort = uiPin / 32U;
286
287 assert(uiPort < NUM_SUPPORTED_PORTS); // Must map to a port
288 assert(uiNumPins > 0U); // Must be at least 1 pin long
289 assert(uiNumPins <= 32U); // Must be no more than 32 pins long
290 assert(uiPort == (uiPin + uiNumPins - 1U) / 32U); // First and last pin must be on the same port
291
292 uiPin &= 31U;
293 return GPIO_PinsRead(GPIOBaseArray[uiPort], uiPin, 1UL << uiNumPins);
294 }
295
303 static void sGPIO_PinWrite( uint32_t uiPin, uint32_t uiOutput )
304 {
305 uint32_t uiPort = uiPin / 32U;
306
307 assert(uiPort < NUM_SUPPORTED_PORTS); // Must map to a port
308
309 uiPin &= 31U;
310 GPIO_PinWrite(GPIOBaseArray[uiPort], uiPin, uiOutput);
311 }
312
321 static void sGPIO_PinsWrite( uint32_t uiPin, uint32_t uiNumPins, uint32_t uiOutput )
322 {
323 uint32_t uiPort = uiPin / 32U;
324 uint32_t uiMask;
325
326 assert(uiPort < NUM_SUPPORTED_PORTS); // Must map to a port
327 assert(uiNumPins > 0U); // Must be at least 1 pin long
328 assert(uiNumPins <= 32U); // Must be no more than 32 pins long
329 assert(uiPort == (uiPin + uiNumPins - 1U) / 32U); // First and last pin must be on the same port
330
331 uiPin &= 31U;
332 uiMask = 1U << uiNumPins;
333
334 GPIO_PinsWrite(GPIOBaseArray[uiPort], uiPin, uiMask, uiOutput);
335 }
336
345 static void * sMalloc( uint32_t uiSize )
346 {
347 void * pvPtr;
348
349 pvPtr = pvPortMalloc( (size_t) uiSize );
350 if (pvPtr != NULL)
351 {
352 memset(pvPtr, 0, uiSize);
353 }
354
355 return pvPtr;
356 }
357
364 static void sFree( void * pvPtr )
365 {
366 vPortFree( pvPtr );
367 }
368
377 static void sAssert(const char * pachBuffer, const char * pachFilename, int iLineNumber )
378 {
379 // FIXME
380 }
381
382 typedef int (*pfn_snprintf_t)(char *, uint32_t, const char *, ...);
383
384 // ----------------------------------------------
385 // Create a NONE Sampler
386 // ----------------------------------------------
387
388 bool Sampler_NONE_Setup( const ePLATFORM_SamplerConfig_t *paeSamplerConfig,
389 uint32_t uiNumChannels,
390 volatile stPLATFORM_SampleGrab_t * pastCircularBuffer,
391 uint32_t uiBufferElements )
392 {
393 (void)paeSamplerConfig;
394 (void)uiNumChannels;
395 (void)pastCircularBuffer;
396 (void)uiBufferElements;
397
398 return false;
399 }
400
401 bool Sampler_NONE_Start(uint32_t uiPeriod_Nsec)
402 {
403 (void)uiPeriod_Nsec;
404
405 return false;
406 }
407
408 bool Sampler_NONE_Adjust(uint32_t uiDelay_Nsec, uint32_t uiPeriod_Nsec)
409 {
410 (void)uiDelay_Nsec;
411 (void)uiPeriod_Nsec;
412
413 return false;
414 }
415
416 bool Sampler_NONE_Stop(void)
417 {
418 return false;
419 }
420
421 uint32_t Sampler_NONE_GetTimer(void)
422 {
423 return 0;
424 }
425
426 uint32_t Sampler_NONE_Grab( uint32_t uiEarliestTimer,
427 volatile stPLATFORM_SampleGrab_t ** papstGrabArray,
428 uint32_t uiMaxSamplesToGrab)
429 {
430 (void)uiEarliestTimer;
431 (void)papstGrabArray;
432 (void)uiMaxSamplesToGrab;
433
434 return 0;
435 }
436
437 typedef struct
438 {
439 eWebFlags_t eWebFlags;
440 const char * pachHeader;
441 } stContentHeader_t;
442
443 static const stContentHeader_t astContentHeader[] =
444 {
445 { eWebFlags_HTML, "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n" },
446 { eWebFlags_JavaScript, "HTTP/1.1 200 OK\r\nContent-type: text/javascript\r\n\r\n" },
447 { eWebFlags_CSS, "HTTP/1.1 200 OK\r\nContent-type: text/css\r\n\r\n" },
448 { eWebFlags_GIF, "HTTP/1.1 200 OK\r\nContent-type: image/gif\r\n\r\n" },
449 { eWebFlags_JPG, "HTTP/1.1 200 OK\r\nContent-type: image/jpeg\r\n\r\n" },
450 { eWebFlags_PNG, "HTTP/1.1 200 OK\r\nContent-type: image/png\r\n\r\n" },
451 { eWebFlags_WEBP, "HTTP/1.1 200 OK\r\nContent-type: image/webp\r\n\r\n" },
452 { eWebFlags_PDF, "HTTP/1.1 200 OK\r\nContent-type: application/pdf\r\n\r\n" },
453 { eWebFlags_JSON, "HTTP/1.1 200 OK\r\nContent-type: application/json\r\n\r\n" }
454 };
455
456 static const char * GetContentHeader(eWebFlags_t eWebFlags)
457 {
458 int i;
459
460 for (i = 0; i < NUM_ELEMENTS(astContentHeader); i++)
461 {
462 if (astContentHeader[i].eWebFlags & eWebFlags)
463 {
464 return astContentHeader[i].pachHeader;
465 }
466 }
467
468 return astContentHeader[0].pachHeader; // i.e. default to text/html
469 }
470
471 static bool FileAdd( const char * pachFileName, eWebFlags_t eWebFlags, const char * pachFiledata, uint32_t uiFilesize )
472 {
473 const char * pachContentHeader;
474 bool bKeepAlive;
475
476 pachContentHeader = GetContentHeader(eWebFlags);
477 bKeepAlive = (eWebFlags & eWebFlags_KeepAlive) ? true : false;
478
479 return StaticFileAdd(pachFileName, pachContentHeader, pachFiledata, uiFilesize, bKeepAlive);
480 }
481
482 static bool CgiAdd( const char * pachCgiName, pfnCgiCallback_t pfnCgiCallback )
483 {
484 return DynamicCgiAdd(pachCgiName, pfnCgiCallback);
485 }
486
495 static bool DNS_SD_Discovery(void (*pfnResponseCallback)(const char *pachResponse, uint32_t uiResponseLen))
496 {
497 // Stub for now!
498 return true;
499 }
500
501 // ----------------------------------------------
502 // Define our FreeRTOS platform call table
503 // ----------------------------------------------
504
505 const stPlatformCalls_t stPlatformCalls_FreeRTOS =
506 {
507 // Task platform calls
508 &sTaskCreate,
509 &sTaskSleep,
510 &sTaskGetTickCount,
511
512 // GPIO Platform calls
513 &sGPIO_PinInit,
514 &sGPIO_PinReadPadStatus,
515 &sGPIO_PinSetInterruptConfig,
516 &sGPIO_PinRead,
517 &sGPIO_PinsRead,
518 &sGPIO_PinWrite,
519 &sGPIO_PinsWrite,
520
521 // Coap platform calls
522 &CoAP_CreateResource,
523 &CoAP_ObjectUpdated,
524
525 // Other platform calls
526 &sMalloc,
527 &sFree,
528 &sGetTimestamp,
529 &printf, // Call platform-side printf() directly
530 (pfn_snprintf_t)&snprintf, // Call platform-side snprintf() directly (FIXME: make this safe in a separate Jira!)
531 &sAssert,
532
533 // Sampler services
534 &Sampler_NONE_Setup,
535 &Sampler_NONE_Start,
536 &Sampler_NONE_Adjust,
537 &Sampler_NONE_Stop,
538 &Sampler_NONE_GetTimer,
539 &Sampler_NONE_Grab,
540
541 (void * (*)(void *, const void *, uint32_t)) &memcpy,
542 (void * (*)(const void *, const void *, uint32_t)) &memcmp,
543 (void * (*)(void *, int, uint32_t)) &memset,
544 &strcpy,
545 &strcmp,
546 (int (*)(const char *))&strlen,
547
548 &FileAdd,
549 &CgiAdd,
550 &DNS_SD_Discovery
551 };
552
NULL
#define NULL
Definition: bootloader_common.h:26
auxPriorityTable
static const UBaseType_t auxPriorityTable[ePLATFORM_TaskPriority_MAX]
Definition: platform_main_freertos.c:29
Sampler_NONE_Grab
uint32_t Sampler_NONE_Grab(uint32_t uiEarliestTimer, volatile stPLATFORM_SampleGrab_t **papstGrabArray, uint32_t uiMaxSamplesToGrab)
Definition: platform_main_freertos.c:426
Sampler_NONE_Start
bool Sampler_NONE_Start(uint32_t uiPeriod_Nsec)
Definition: platform_main_freertos.c:401
stPlatformCalls_FreeRTOS
const stPlatformCalls_t stPlatformCalls_FreeRTOS
Definition: platform_main_freertos.c:505
pfn_snprintf_t
int(* pfn_snprintf_t)(char *, uint32_t, const char *,...)
Definition: platform_main_freertos.c:382
GPIO1
#define GPIO1
Definition: MIMXRT1062.h:20740
GPIO_Type::DR
__IO uint32_t DR
Definition: MIMXRT1062.h:20330
sTaskGetTickCount
static volatile uint32_t sTaskGetTickCount(void)
Get the current task's tickcount value.
Definition: platform_main_freertos.c:195
sAssert
static void sAssert(const char *pachBuffer, const char *pachFilename, int iLineNumber)
Assert support call.
Definition: platform_main_freertos.c:377
i
volatile int i
Definition: excep_test.c:17
ahTaskHandles
static TaskHandle_t ahTaskHandles[PLUGINS_MAX][ePLATFORM_TaskSlot_MAX]
Definition: platform_main_freertos.c:53
CoAP_ObjectUpdated
void CoAP_ObjectUpdated(const stPLATFORM_ObjectData_t *pstObjectData)
Definition: platform_coap.c:206
sGPIO_PinWrite
static void sGPIO_PinWrite(uint32_t uiPin, uint32_t uiOutput)
Write a value out to single GPIO pin.
Definition: platform_main_freertos.c:303
astContentHeader
static const stContentHeader_t astContentHeader[]
Definition: platform_main_freertos.c:443
GPIO4
#define GPIO4
Definition: MIMXRT1062.h:20752
sGPIO_PinReadPadStatus
static uint8_t sGPIO_PinReadPadStatus(uint32_t uiPin)
Read a GPIO pin's pad status.
Definition: platform_main_freertos.c:231
Sampler_NONE_GetTimer
uint32_t Sampler_NONE_GetTimer(void)
Definition: platform_main_freertos.c:421
assert
#define assert(CONDITION)
Definition: platform_startup.c:68
Sampler_NONE_Setup
bool Sampler_NONE_Setup(const ePLATFORM_SamplerConfig_t *paeSamplerConfig, uint32_t uiNumChannels, volatile stPLATFORM_SampleGrab_t *pastCircularBuffer, uint32_t uiBufferElements)
Definition: platform_main_freertos.c:388
sTaskSleep
static void sTaskSleep(uint32_t uiMsec)
Sleep the current task for a specified number of milliseconds.
Definition: platform_main_freertos.c:184
CoAP_CreateResource
bool CoAP_CreateResource(stPLATFORM_ObjectData_t *pstObjectData)
Definition: platform_coap.c:180
Sampler_NONE_Stop
bool Sampler_NONE_Stop(void)
Definition: platform_main_freertos.c:416
GPIO_PinsRead
static uint32_t GPIO_PinsRead(GPIO_Type *base, uint32_t uiPin, uint32_t uiPinMask)
Read multiple GPIO pins at once.
Definition: platform_main_freertos.c:84
DNS_SD_Discovery
static bool DNS_SD_Discovery(void(*pfnResponseCallback)(const char *pachResponse, uint32_t uiResponseLen))
Definition: platform_main_freertos.c:495
GPIO2
#define GPIO2
Definition: MIMXRT1062.h:20744
sMalloc
static void * sMalloc(uint32_t uiSize)
Allocate memory.
Definition: platform_main_freertos.c:345
stContentHeader_t::eWebFlags
eWebFlags_t eWebFlags
Definition: platform_main_freertos.c:439
GPIO3
#define GPIO3
Definition: MIMXRT1062.h:20748
FileAdd
static bool FileAdd(const char *pachFileName, eWebFlags_t eWebFlags, const char *pachFiledata, uint32_t uiFilesize)
Definition: platform_main_freertos.c:471
sGPIO_PinsRead
static uint32_t sGPIO_PinsRead(uint32_t uiPin, uint32_t uiNumPins)
Read multiple GPIO pins in one go.
Definition: platform_main_freertos.c:283
sGPIO_PinSetInterruptConfig
static void sGPIO_PinSetInterruptConfig(uint32_t uiPin, ePLATFORM_interrupt_mode_t pinInterruptMode)
Configure the interrupt settings for a given GPIO pin.
Definition: platform_main_freertos.c:247
GPIOBaseArray
static GPIO_Type *const GPIOBaseArray[]
Definition: platform_main_freertos.c:58
STACKDEPTH_IN_BYTES
#define STACKDEPTH_IN_BYTES
Definition: platform_main_freertos.c:23
sGetTimestamp
static bool sGetTimestamp(stPLATFORM_Timestamp_t *pstTimestamp)
Get a PTP timestamp.
Definition: platform_main_freertos.c:119
CgiAdd
static bool CgiAdd(const char *pachCgiName, pfnCgiCallback_t pfnCgiCallback)
Definition: platform_main_freertos.c:482
sGPIO_PinInit
static void sGPIO_PinInit(uint32_t uiPin, const stPLATFORM_pin_config_t *pstConfig)
Initialise a GPIO pin.
Definition: platform_main_freertos.c:207
stContentHeader_t
Definition: platform_main_freertos.c:437
GPIO_Type
Definition: MIMXRT1062.h:20329
platform_coap.h
sGPIO_PinRead
static uint32_t sGPIO_PinRead(uint32_t uiPin)
Read a single GPIO pin.
Definition: platform_main_freertos.c:266
GPIO_PinsWrite
static void GPIO_PinsWrite(GPIO_Type *base, uint32_t uiPin, uint32_t uiPinMask, uint32_t uiNewValue)
Write multiple GPIO pins at once.
Definition: platform_main_freertos.c:98
Sampler_NONE_Adjust
bool Sampler_NONE_Adjust(uint32_t uiDelay_Nsec, uint32_t uiPeriod_Nsec)
Definition: platform_main_freertos.c:408
auxInterruptModeTable
static const UBaseType_t auxInterruptModeTable[ePLATFORM_Int_MAX]
Definition: platform_main_freertos.c:38
sFree
static void sFree(void *pvPtr)
Free previously-allocated memory block.
Definition: platform_main_freertos.c:364
GetContentHeader
static const char * GetContentHeader(eWebFlags_t eWebFlags)
Definition: platform_main_freertos.c:456
sGPIO_PinsWrite
static void sGPIO_PinsWrite(uint32_t uiPin, uint32_t uiNumPins, uint32_t uiOutput)
Write a value out across a set of multiple GPIO pins.
Definition: platform_main_freertos.c:321
stContentHeader_t::pachHeader
const char * pachHeader
Definition: platform_main_freertos.c:440
sTaskCreate
static bool sTaskCreate(uint32_t uiPluginIndex, ePLATFORM_TaskSlot_t eTaskSlot, void(*pvTaskCode)(void *pvParams), const char *const pcTaskName, void *pvParams, uint32_t uiStackSizeInBytes, ePLATFORM_TaskPriority_t ePriority)
Create and launch a new plugin task.
Definition: platform_main_freertos.c:148
NUM_SUPPORTED_PORTS
#define NUM_SUPPORTED_PORTS
Definition: platform_main_freertos.c:66