From 78688c27c58da751cd2cf761f13b609ede8e9b7f Mon Sep 17 00:00:00 2001 From: Jacob Chisholm Date: Sat, 17 Feb 2024 18:12:02 -0500 Subject: [PATCH] all working --- Q24ECU/core/config/pins.h | 3 -- Q24ECU/core/include/main.h | 4 +++ Q24ECU/core/include/taskHandlers.h | 3 +- Q24ECU/core/src/interfaces/interface_uart.c | 10 ++++-- Q24ECU/core/src/main.c | 40 +++++++++++++-------- Q24ECU/core/src/syscalls.c | 11 ++++-- Q24ECU/core/src/taskHandlers.c | 1 + Q24ECU/core/src/tasks/canRunner.c | 9 ++--- Q24ECU/docs/FreeRTOS.md | 15 ++++++++ Q24ECU/{ => docs}/clangd_fixes_unknown.md | 0 Q24ECU/readme.md | 13 +++++-- 11 files changed, 80 insertions(+), 29 deletions(-) create mode 100644 Q24ECU/docs/FreeRTOS.md rename Q24ECU/{ => docs}/clangd_fixes_unknown.md (100%) diff --git a/Q24ECU/core/config/pins.h b/Q24ECU/core/config/pins.h index 4ad8f97a..d09d37e7 100644 --- a/Q24ECU/core/config/pins.h +++ b/Q24ECU/core/config/pins.h @@ -42,9 +42,6 @@ // Vin Voltage Divider #define PIN_voltageSensor ((uint16_t)(PIN('C', 1))) -// Debug USART (for printf) -#define UART_DEBUG USART2 - #define PIN_CAN1_RX ((uint16_t)(PIN('A', 11))) #define PIN_CAN1_TX ((uint16_t)(PIN('A', 12))) diff --git a/Q24ECU/core/include/main.h b/Q24ECU/core/include/main.h index 591c3c3a..116a2b55 100644 --- a/Q24ECU/core/include/main.h +++ b/Q24ECU/core/include/main.h @@ -14,6 +14,10 @@ #include "nvicConfig.h" #include "interrupts.h" +// Comment this out to remove task names from the debug print +#define DEBUG_PRINTF_TASK_NAME + + extern void SystemInit(void); extern int main(void); diff --git a/Q24ECU/core/include/taskHandlers.h b/Q24ECU/core/include/taskHandlers.h index 0a784a6b..812269f3 100644 --- a/Q24ECU/core/include/taskHandlers.h +++ b/Q24ECU/core/include/taskHandlers.h @@ -22,7 +22,8 @@ enum Tasks{ eTask_CAN_send, eTask_CAN_receive, eTask_CAN_rxBufferHandler, - eTask_TaskCount // Keep this last + // Keep this last + eTask_TaskCount // Number of tasks running on the system (`taskHandlers.h`) }; extern TaskHandle_t xTaskHandles[eTask_TaskCount]; diff --git a/Q24ECU/core/src/interfaces/interface_uart.c b/Q24ECU/core/src/interfaces/interface_uart.c index c87b2c7b..792bfc70 100644 --- a/Q24ECU/core/src/interfaces/interface_uart.c +++ b/Q24ECU/core/src/interfaces/interface_uart.c @@ -19,6 +19,9 @@ uart_t port_uart2; uart_t port_uart4; +// UART Baud Rate (Bits per Second) +#define UART_BAUD 250000 + /** * @brief OS UART Setup handler @@ -31,13 +34,16 @@ uart_t port_uart4; * */ void os_uart_setup(void){ + // Enable the UART 2 port and setup its IQR handler - uart_send_init(&port_uart2, USART2, 115200, PIN_USART2_TX, PIN_USART2_RX); - uart_send_init(&port_uart4, UART4, 115200, PIN('A', 0), PIN('A', 1)); + uart_send_init(&port_uart2, USART2, UART_BAUD, PIN_USART2_TX, PIN_USART2_RX); xStreamBufferSetTriggerLevel(port_uart2.rxbuffer, 5); // set the trigger level of the stream buffer. Port Specific. hal_uart_enable_rxne(port_uart2.port, true); NVIC_SetPriority(USART2_IRQn, (NVIC_Priority_MIN-10)); NVIC_EnableIRQ(USART2_IRQn); + + // Enable the UART 4 port (NO IRQ handler for receiving data) + uart_send_init(&port_uart4, UART4, UART_BAUD, PIN_UART4_TX, PIN_UART4_RX); } void USART2_IRQHandler(void){ diff --git a/Q24ECU/core/src/main.c b/Q24ECU/core/src/main.c index 83020ec9..23e053e7 100644 --- a/Q24ECU/core/src/main.c +++ b/Q24ECU/core/src/main.c @@ -17,37 +17,40 @@ #include "stm32f446xx.h" int main(void){ - // set up gpio - // gpio_set_mode(debug_led1, GPIO_MODE_OUTPUT); - // gpio_write(debug_led1, false); - // gpio_set_mode(debug_led2, GPIO_MODE_OUTPUT); - // gpio_write(debug_led2, true); - // gpio_pull(debug_led1, GPIO_PULLDOWN); + + // Initialize Timer Interrupts // Enable Timer 6 (Basic Timer) 1Hz (APB2/45000, count to 2000) // TIM_basic_Init(TIM6, 45000U, 2000U); // NVIC_SetPriority(TIM6_DAC_IRQn, NVIC_Priority_MIN); // Enable Timer IRQ (lowest priority) // NVIC_EnableIRQ(TIM6_DAC_IRQn); + + // Initialize OS Interfaces + + os_uart_setup(); // clear terminal printf("\033[2J"); - // initialize os interfaces - os_uart_setup(); + printf("\n"); printf("USART Initialized..\n"); - // hal_uart_init(UART4, 115200, PIN('A', 0), PIN('A', 1)); - + os_can_setup(); - printf("CAN Initialized..\n"); + printf("CAN Bus Initialized..\n"); + spin(9999999UL); - printf("system starting tasks...\n"); + + printf("System Starting Tasks...\n\n"); + spin(9999999UL); // Initialize all the tasks os_task_init(); + // Print out Task Information + printf("Task:\t Identifier\t Priority\t\tState\n"); for (int i = 0; i < eTask_TaskCount; i++) { - printf("Task %d: %s\t", i, pcTaskGetName(xTaskHandles[i])); + printf("%d: %16s\t\t%lu\t\t", i, pcTaskGetName(xTaskHandles[i]), uxTaskPriorityGet(xTaskHandles[i])); switch(eTaskGetState(xTaskHandles[i])) { case eRunning: printf("RUNNING\n"); @@ -72,7 +75,15 @@ int main(void){ break; } } - + + printf("\n"); + printf("Total Heap Memory: %d B\n", configTOTAL_HEAP_SIZE); + printf("Free Heap Memory: %d B\n", xPortGetFreeHeapSize()); + printf("\n"); + + + printf("Starting Scheduler...\n"); + printf("\n"); // Start Scheduler vTaskStartScheduler(); @@ -81,6 +92,7 @@ int main(void){ for(;;) { // Write out Error LED // gpio_write(debug_led2, false); + __asm__("nop"); } return 0; } diff --git a/Q24ECU/core/src/syscalls.c b/Q24ECU/core/src/syscalls.c index a527d082..b87abd89 100644 --- a/Q24ECU/core/src/syscalls.c +++ b/Q24ECU/core/src/syscalls.c @@ -6,6 +6,7 @@ #include "interfaces/interface_uart.h" #include "FreeRTOS.h" #include "task.h" +#include "main.h" #include "string.h" int _fstat(int fd, struct stat *st) { @@ -76,7 +77,7 @@ int _lseek(int fd, int ptr, int dir) { void _exit(int status) { (void) status; - for (;;) asm volatile("BKPT #0"); + for (;;) __asm__ volatile("BKPT #0"); } void _kill(int pid, int sig) { @@ -90,18 +91,22 @@ int _getpid(void) { int _write(int fd, char *ptr, int len) { (void) fd, (void) ptr, (void) len; if (fd == 1 || fd == 2){ + #ifdef DEBUG_PRINTF_TASK_NAME char * callerID = NULL; // Get the name of the task calling printf - Only run if scheduler has been started if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) callerID = pcTaskGetName(NULL); + #endif if(port_uart2.port == NULL) return -1; if(port_uart2.semaphore == NULL) return -1; // Take over the debug usart - if(xSemaphoreTake(port_uart2.semaphore, (TickType_t) 100) == pdTRUE){ + if(xSemaphoreTake(port_uart2.semaphore, (TickType_t) 10) == pdTRUE){ + #ifdef DEBUG_PRINTF_TASK_NAME // Write caller ID, followed by ": ", then the argument given to printf if(callerID != NULL){ hal_uart_write_buf(port_uart2.port, callerID, strlen(callerID)); hal_uart_write_buf(port_uart2.port, ": ", 3); } + #endif hal_uart_write_buf(port_uart2.port, ptr, (size_t) len); xSemaphoreGive(port_uart2.semaphore); } @@ -112,7 +117,7 @@ int _write(int fd, char *ptr, int len) { int _read(int fd, char *ptr, int len) { (void) fd, (void) ptr, (void) len; - // should be able to use calloc to allocate memory and read usart + // There is no filesystem return -1; } diff --git a/Q24ECU/core/src/taskHandlers.c b/Q24ECU/core/src/taskHandlers.c index f282bda7..0db71943 100644 --- a/Q24ECU/core/src/taskHandlers.c +++ b/Q24ECU/core/src/taskHandlers.c @@ -12,6 +12,7 @@ #include "taskHandlers.h" #include + // Init global handles for tasks TaskHandle_t xTaskHandles[eTask_TaskCount]; diff --git a/Q24ECU/core/src/tasks/canRunner.c b/Q24ECU/core/src/tasks/canRunner.c index 7e88804d..ec4f2b9d 100644 --- a/Q24ECU/core/src/tasks/canRunner.c +++ b/Q24ECU/core/src/tasks/canRunner.c @@ -19,8 +19,8 @@ void vTask_CAN_send(void *param){ (void)param; - - printf("CAN Send Running\n"); + vTaskDelay(1); + printf("Initializing TX\n"); uart_send_buf_blocking(&port_uart4, "Running CAN TX Task from canRunner.c\n", 38U, 1000U); can_msg_t tx_msg; tx_msg.id = 33; @@ -40,13 +40,14 @@ void vTask_CAN_send(void *param){ void vTask_CAN_receive(void *param){ (void)param; - printf("CAN RX Running\n"); + vTaskDelay(1); + printf("Initializing RX\n"); uart_send_buf_blocking(&port_uart4, "Running CAN RX Task from canRunner.c\n", 38U, 1000U); can_msg_t rx_msg; for(;;){ rx_msg = can_fetch(CAN1, 200); char buf[40]; - snprintf(buf, 40, "%d: %d\n", rx_msg.id, rx_msg.data[0]); + snprintf(buf, 40, "%ld: %d\n", rx_msg.id, rx_msg.data[0]); uart_send_buf_blocking(&port_uart4, buf, strlen(buf), 1000); vTaskDelay(100); } diff --git a/Q24ECU/docs/FreeRTOS.md b/Q24ECU/docs/FreeRTOS.md new file mode 100644 index 00000000..c7afc04d --- /dev/null +++ b/Q24ECU/docs/FreeRTOS.md @@ -0,0 +1,15 @@ +# Basic FreeRTOS Information + +This project uses the FreeRTOS real time scheduler in conjunction with a custom developed HAL. View the [FreeRTOS Docs Here](https://www.freertos.org/features.html). + +Some basic information about the project: +- Heap 4 implementation is used +- Objects are statically allocated where possible. +- Cortex M4 Floating Point Unit is enabled +- 32 Levels of task priority +- 1kHz scheduler tick rate +- Mutexes and Counting Semaphores used +- `xTaskDelayUntil` Used for preemptive scheduling + + +*The FreeRTOS configuration used is adapted from the STM32 Cube Default Configuration* \ No newline at end of file diff --git a/Q24ECU/clangd_fixes_unknown.md b/Q24ECU/docs/clangd_fixes_unknown.md similarity index 100% rename from Q24ECU/clangd_fixes_unknown.md rename to Q24ECU/docs/clangd_fixes_unknown.md diff --git a/Q24ECU/readme.md b/Q24ECU/readme.md index 0d4d169d..9cc93c8b 100644 --- a/Q24ECU/readme.md +++ b/Q24ECU/readme.md @@ -6,22 +6,31 @@ Author: Jacob Chisholm Written for Queen's Formula SAE ## V2 Notes -- Built with RTOS +- Built with FreeRTOS - CMAKE compiling/linking with GCC - Makefile uploading (binary blobs produced cross compatible) ## Running + +#### VS Code 1. Select correct compiler kit in VS code cMake extension 2. Allow cMake automatic configuration 3. Select flash method in the makefile 3. Run `make flash` or upload code with another method +#### MakeFile +1. Run `make cmake` to generate cmake configuration files +2. Run `make build` to build the project +3. Select the flash method in the makefile +4. Run `make flash` + + ## Required Softwares: - GCC - arm-none-eabi-gcc - arm-none-eabi-objcopy - arm-none-eabi-gdb -- make +- GNU make - VS Code - cMake extension - Teleplot extension (for plotting serial data)