diff options
| author | Aditya Naik | 2020-06-09 17:13:54 -0400 |
|---|---|---|
| committer | Aditya Naik | 2020-06-09 17:13:54 -0400 |
| commit | b51d58287649d42c6097244bb66343b0806b26fe (patch) | |
| tree | e5bd1f3ce518f80e2db2596fbad7e8eb6da49d21 | |
| parent | 5e598a70d53c070a3465493a9e926717243fb844 (diff) | |
Consolidated rtos-master.c and master.crtos
| -rw-r--r-- | makefile | 3 | ||||
| -rw-r--r-- | src/master.c | 175 |
2 files changed, 153 insertions, 25 deletions
@@ -22,7 +22,6 @@ BUILD_DIR = build ######################################
# C sources for all ports
C_SOURCES = \
-src/main-rtos.c \
lib/nanopb/pb_decode.c \
lib/nanopb/pb_encode.c \
lib/nanopb/pb_common.c \
@@ -73,7 +72,7 @@ AS_INCLUDES = C_INCLUDES = \
-Isrc \
-Ilib/cmsis \
--Ilib/freertos/include
+-Ilib/freertos/include \
-Ilib/nanopb
# Define the chip we're building for and include its makefile
diff --git a/src/master.c b/src/master.c index c627a45..a23805b 100644 --- a/src/master.c +++ b/src/master.c @@ -15,6 +15,8 @@ /* Library includes */ #include <pb_encode.h> #include <pb_decode.h> +#include "FreeRTOS.h" +#include "task.h" /* Project includes */ #include "main.h" @@ -23,6 +25,7 @@ #include "dataflow.h" #include "handshake.pb.h" #include "data.pb.h" +#include "semphr.h" /* Private Macros */ #define device_MDR s2m_MDR_response @@ -38,6 +41,12 @@ /* Macro to toggle between master and slave firmware */ #define MASTER +#define mainHANDSHAKE_TASK_PRIORITY (tskIDLE_PRIORITY + 2) +#define mainROUTING_TASK_PRIORITY (tskIDLE_PRIORITY + 2) +#define mainDATAFLOW_TASK_PRIORITY (tskIDLE_PRIORITY + 1) +#define mainHS_FREQUENCY_MS (2000 / portTICK_PERIOD_MS) +#define mainQUEUE_LENGTH (1) + /* Private globals */ I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart1; @@ -63,14 +72,22 @@ static void MX_USART1_UART_Init(void); hs_status_t handshake(uint32_t i2c_addr); dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t routing_buf_idx); bool routing(void); + +static void prvHandshakeTask(void *pvParameters); +static void prvRoutingTask(void *prvParam); +static void prvDataflowTask(void *prvParam); + bool todo_hs_or_not_todo_hs(uint8_t i2c_addr); state_t get_state_from_hs_status(uint16_t device_addr, hs_status_t hs_status); + bool decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *field, void **args); bool encode_subscription_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg); bool encode_datapoint_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg); bool decode_data_callback(pb_istream_t *istream, const pb_field_t *field, void **args); bool master_encode_MDR_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg); + + /** * @brief The application entry point. * @retval int @@ -99,37 +116,69 @@ int main(void) HAL_UART_Transmit(&huart1, reset_string, sizeof(reset_string), 100); #endif /* MASTER */ #endif /* TESTING_ENABLE */ + uint8_t priority_counter = 0, debug_buf[128]; - /* Handshake */ - while (1) { - if (priority_counter == 0) { - hs_status_t hs_status; - /* for (uint8_t curr_addr=5; curr_addr == 5; curr_addr++) { */ - for (uint8_t curr_addr=0x1; curr_addr <= BUS_DEVICE_LIMIT; curr_addr++) { - if (todo_hs_or_not_todo_hs(curr_addr)) { - hs_status = handshake(curr_addr); - dev_sts[GET_IDX_FROM_ADDR(curr_addr)] = get_state_from_hs_status(curr_addr, hs_status); - } + xTaskCreate(prvHandshakeTask, "handshake", configMINIMAL_STACK_SIZE, NULL, + mainHANDSHAKE_TASK_PRIORITY,NULL); + + xTaskCreate(prvRoutingTask, "routing", configMINIMAL_STACK_SIZE, NULL, + mainROUTING_TASK_PRIORITY, NULL); + + xTaskCreate(prvDataflowTask, "dataflow", configMINIMAL_STACK_SIZE, NULL, + mainDATAFLOW_TASK_PRIORITY, NULL); + /* Start the tasks and timer running. */ + vTaskStartScheduler(); + for( ;; ); +} + +static void prvHandshakeTask(void *pvParameters) +{ + TickType_t xNextWakeTime; + (void) pvParameters; + xNextWakeTime = xTaskGetTickCount(); + for( ;; ) + { + /* Place this task in the blocked state until it is time to run again. */ + vTaskDelayUntil( &xNextWakeTime, mainHS_FREQUENCY_MS ); + hs_status_t hs_status; + for (uint8_t curr_addr=0x1; curr_addr <= BUS_DEVICE_LIMIT; curr_addr++) { + if (todo_hs_or_not_todo_hs(curr_addr)) { + hs_status = handshake(curr_addr); + dev_sts[GET_IDX_FROM_ADDR(curr_addr)] = get_state_from_hs_status(curr_addr, hs_status); } - } + } + } +} - else if (priority_counter == 5 && routing_ptr > 0) { +static void prvRoutingTask(void *prvParam) +{ + TickType_t xNextWakeTime; + (void) prvParam; + xNextWakeTime = xTaskGetTickCount(); + for( ;; ) { + /* Place this task in the blocked state until it is time to run again. */ + vTaskDelayUntil( &xNextWakeTime, mainHS_FREQUENCY_MS ); + if (routing_ptr > 0) { routing(); } - else { - for (int device_idx = 0; device_idx < BUS_DEVICE_LIMIT-1; device_idx++) { - if (dev_sts[device_idx] == REGISTERED) { - device_dataflow(GET_ADDR_FROM_IDX(device_idx), SLAVE_TX, 0); - } + } +} + +static void prvDataflowTask(void *prvParam) +{ + TickType_t xNextWakeTime; + (void) prvParam; + xNextWakeTime = xTaskGetTickCount(); + for( ;; ) { + /* Place this task in the blocked state until it is time to run again. */ + vTaskDelayUntil( &xNextWakeTime, mainHS_FREQUENCY_MS ); + for (int device_idx = 0; device_idx < BUS_DEVICE_LIMIT-1; device_idx++) { + if (dev_sts[device_idx] == REGISTERED) { + device_dataflow(GET_ADDR_FROM_IDX(device_idx), SLAVE_TX, 0); } } - priority_counter = ((priority_counter+1)%10); - - sprintf((char*)debug_buf, "routing ptr: %ld\r\n", routing_ptr); - HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); - memset(debug_buf, 0, 128); - } + } } hs_status_t handshake(uint32_t i2c_addr) @@ -983,3 +1032,83 @@ void assert_failed(uint8_t *file, uint32_t line) /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ + +// Macro to use CCM (Core Coupled Memory) in STM32F4 +#define CCM_RAM __attribute__((section(".ccmram"))) + +#define FPU_TASK_STACK_SIZE 256 + +StackType_t fpuTaskStack[FPU_TASK_STACK_SIZE] CCM_RAM; // Put task stack in CCM +StaticTask_t fpuTaskBuffer CCM_RAM; // Put TCB in CCM + +void vApplicationTickHook(void) { +} + +/* vApplicationMallocFailedHook() will only be called if + configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook + function that will get called if a call to pvPortMalloc() fails. + pvPortMalloc() is called internally by the kernel whenever a task, queue, + timer or semaphore is created. It is also called by various parts of the + demo application. If heap_1.c or heap_2.c are used, then the size of the + heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in + FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used + to query the size of free heap space that remains (although it does not + provide information on how the remaining heap might be fragmented). */ +void vApplicationMallocFailedHook(void) { + taskDISABLE_INTERRUPTS(); + for(;;); +} + +/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set + to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle + task. It is essential that code added to this hook function never attempts + to block in any way (for example, call xQueueReceive() with a block time + specified, or call vTaskDelay()). If the application makes use of the + vTaskDelete() API function (as this demo application does) then it is also + important that vApplicationIdleHook() is permitted to return to its calling + function, because it is the responsibility of the idle task to clean up + memory allocated by the kernel to any task that has since been deleted. */ +void vApplicationIdleHook(void) { +} + +void vApplicationStackOverflowHook(xTaskHandle pxTask, signed char *pcTaskName) { + (void) pcTaskName; + (void) pxTask; + /* Run time stack overflow checking is performed if + configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook + function is called if a stack overflow is detected. */ + taskDISABLE_INTERRUPTS(); + for(;;); +} + +StaticTask_t xIdleTaskTCB CCM_RAM; +StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE] CCM_RAM; + +/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an +implementation of vApplicationGetIdleTaskMemory() to provide the memory that is +used by the Idle task. */ +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) { + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} + +static StaticTask_t xTimerTaskTCB CCM_RAM; +static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH] CCM_RAM; + +/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the +application must provide an implementation of vApplicationGetTimerTaskMemory() +to provide the memory that is used by the Timer service task. */ +void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) { + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} |
