]> wirehaze git hosting - stm32f411ceu6.git/commitdiff

wirehaze git hosting

organize
authorphfr24 <phfr24@inf.ufpr.br>
Sun, 12 Jul 2026 20:25:43 +0000 (17:25 -0300)
committerphfr24 <phfr24@inf.ufpr.br>
Sun, 12 Jul 2026 20:25:43 +0000 (17:25 -0300)
Makefile
exceptions.c [new file with mode: 0644]
kentry.c
kernel.c [deleted file]
led.c [new file with mode: 0644]
led.h [new file with mode: 0644]
sysclk.c [new file with mode: 0644]
sysclk.h [new file with mode: 0644]
uart.c [new file with mode: 0644]
uart.h [new file with mode: 0644]

index f0ec81fe237821b2eb3c8a6c2b4d8edea4f0e4dd..3c19779dd381e2ce818e91b41b5942198987d304 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -32,6 +32,7 @@ CFLAGS := -march=armv7e-m+fp \
                                        -Wextra \
                                        -Wconversion \
                                        -Wstrict-prototypes \
                                        -Wextra \
                                        -Wconversion \
                                        -Wstrict-prototypes \
+                                       -Wmissing-prototypes \
                                        -Wshadow \
                                        -Wundef \
                                        -Wdouble-promotion \
                                        -Wshadow \
                                        -Wundef \
                                        -Wdouble-promotion \
@@ -46,7 +47,7 @@ OCFLAGS := --output-target=binary
 
 #  ---------------------------------------------------------------------------  #
 
 
 #  ---------------------------------------------------------------------------  #
 
-objs := kernel.o kentry.o
+objs := $(patsubst %.c, %.o, $(wildcard *.c))
 lds := kernel.ld
 LDFLAGS += -T $(lds)
 
 lds := kernel.ld
 LDFLAGS += -T $(lds)
 
diff --git a/exceptions.c b/exceptions.c
new file mode 100644 (file)
index 0000000..b3afaaa
--- /dev/null
@@ -0,0 +1,53 @@
+#include "link.h"
+#include "led.h"
+#include "sysclk.h"
+#include "uart.h"
+
+/* Initialize just enough to be able to handle a fault.  */
+__attribute__ ((noinline, used)) static void
+sys_init (void)
+{
+  unsigned int *src, *dst;
+
+  /* Relocate .data section to SRAM  */
+  src = &_data_lma_start;
+  dst = &_data_vma_start;
+
+  while (dst < &_data_vma_end)
+    *(dst++) = *(src++);
+
+  /* Initialize .bss  */
+  dst = &_bss_vma_start;
+
+  while (dst < &_bss_vma_end)
+    *(dst++) = 0;
+
+  led_init ();
+  sysclk_init ();
+  uart_init ();
+}
+
+/* Startup  */
+__attribute__ ((naked, noreturn)) static void
+reset_handler (void)
+{
+  /* Set FAULTMASK  */
+  asm ("cpsid f");
+
+  /* This function is the core logic for reset_handler (). We just need it so
+   * that when we jump to kentry the stack is empty.  */
+  asm ("bl sys_init");
+
+  /* Clear FAULTMASK  */
+  asm ("cpsie f");
+
+  /* Jump to kernel entry code. When reset_handler () is called we are already
+   * running on Thread mode (Privileged), so we can just jump directly.  */
+  asm ("b kentry");
+}
+
+__attribute__ ((section (".vector_table"), used))
+static unsigned long const vector_table[] = {
+  (unsigned long) &_sram_end,
+  (unsigned long) reset_handler,
+};
index 33b829549499e656dba32db722bab7e972c3f08b..e9eab94499ba19eb28e5deda41f4826b78d1cf5d 100644 (file)
--- a/kentry.c
+++ b/kentry.c
@@ -1,4 +1,7 @@
-#include "stm32f411.h"
+#include "uart.h"
+#include "led.h"
+
+__attribute__ ((noreturn)) void kentry (void);
 
 static const char *text[] = {
   "hello, friend.\r\n",
 
 static const char *text[] = {
   "hello, friend.\r\n",
@@ -15,7 +18,7 @@ static const char *text[] = {
 void
 kentry (void)
 {
 void
 kentry (void)
 {
-  unsigned int line, off;
+  unsigned int line;
 
   /*  Test UART and LED  ----------------------------------------------------  */
 
 
   /*  Test UART and LED  ----------------------------------------------------  */
 
@@ -23,24 +26,8 @@ kentry (void)
     {
       for (line = 0; line < sizeof text / sizeof *text; ++line)
         {
     {
       for (line = 0; line < sizeof text / sizeof *text; ++line)
         {
-          /* Print current line  */
-          off = 0;
-          while (text[line][off])
-            {
-              /* TXE: Transmit data register empty  */
-              while (!(*USART1_SR & (1u << 7))); /* 0: Data is not transferred
-                                                    to the shift register  */
-
-              /* DR[8:0]: Data value  */
-              *USART1_DR = text[line][off++];
-            }
-
-          /* TC: Transmission complete  */
-          while (!(*USART1_SR & (1u << 6))); /* 0: Transmission is not
-                                                complete  */
-
-          /* Blink LED  */
-          *GPIOC_ODR ^= (1u << 13);
+          kputs_busytc (text[line]);
+          led_toggle ();
         }
     }
 }
         }
     }
 }
diff --git a/kernel.c b/kernel.c
deleted file mode 100644 (file)
index 1545c6e..0000000
--- a/kernel.c
+++ /dev/null
@@ -1,100 +0,0 @@
-#include "link.h"
-#include "stm32f411.h"
-
-__attribute__ ((noreturn)) extern void kentry (void);
-
-static void
-reset_handler (void)
-{
-  unsigned int *src, *dst;
-
-  /* Set FAULTMASK  */
-  asm ("cpsid f");
-
-  /*  Initialize .data and .bss in SRAM  ------------------------------------  */
-
-  /* Relocate .data section  */
-  src = &_data_lma_start;
-  dst = &_data_vma_start;
-
-  while (dst < &_data_vma_end)
-    *(dst++) = *(src++);
-
-  /* Initialize .bss  */
-  dst = &_bss_vma_start;
-
-  while (dst < &_bss_vma_end)
-    *(dst++) = 0;
-
-  /*  LED setup  ------------------------------------------------------------  */
-
-  /* GPIOCEN: IO port C clock enable  */
-  *RCC_AHB1ENR |= (1u << 2); /* 1: IO port C clock enabled  */
-  /* MODERy[1:0]: Port x configuration bits (y = 0..15)  */
-  *GPIOC_MODER &= ~(0b11u << 26); /* Clear PC13 bits  */
-  *GPIOC_MODER |= (1u << 26); /* 01: General purpose output mode  */
-
-  /* PC13: 0 = LED on
-   *       1 = LED off  */
-
-  /*  SYSCLK setup  ---------------------------------------------------------  */
-
-  /* HSEBYP: HSE clock bypass  */
-  *RCC_CR &= ~(1u << 18); /* 0: HSE oscillator not bypassed  */
-  /* HSEON: HSE clock enable  */
-  *RCC_CR |= (1u << 16); /* 1: HSE oscillator ON  */
-  /* HSERDY: HSE clock ready flag  */
-  while (!(*RCC_CR & (1u << 17))); /* 0: HSE oscillator not ready  */
-  /* SW: System clock switch  */
-  *RCC_CFGR &= ~(0b11u); /* Clear SW bits  */
-  *RCC_CFGR |= (0b01u); /* 01: HSE oscillator selected as system clock  */
-  /* SWS: System clock switch status  */
-  while ((*RCC_CFGR & (0b11u << 2)) != (0b01u << 2)); /* 01: HSE oscillator used
-                                                         as the system clock  */
-  /* HSION: Internal high-speed clock enable  */
-  *RCC_CR &= ~(1u); /* 0: HSI oscillator OFF  */
-
-  /*  UART setup  -----------------------------------------------------------  */
-
-  /* GPIOAEN: IO port A clock enable  */
-  *RCC_AHB1ENR |= (1u); /* 1: IO port A clock enabled  */
-  /* MODERy[1:0]: Port x configuration bits (y = 0..15)  */
-  *GPIOA_MODER &= ~(0b1111u << 18); /* Clear PA9 and PA10 bits  */
-  *GPIOA_MODER |= (0b1010u << 18); /* 10: Alternate function mode  */
-  /* AFRHy: Alternate function selection for port x bit y (y = 8..15)  */
-  *GPIOA_AFRH &= ~(0b11111111u << 4); /* Clear PA9 and PA10 bits  */
-  *GPIOA_AFRH |= (0b01110111u << 4); /* 0111: AF7  */
-
-  /* PA9: USART1_TX
-   * PA10: USART1_RX  */
-
-  /* USART1EN: USART1 clock enable  */
-  *RCC_APB2ENR |= (1u << 4); /* 1: USART1 clock enabled  */
-  /* UE: USART enable  */
-  *USART1_CR1 |= (1u << 13); /* 1: USART enable  */
-  /* M: Word length  */
-  *USART1_CR1 &= ~(1u << 12); /* 0: 1 Start bit, 8 Data bits, n Stop bit  */
-  /* PCE: Parity control enable  */
-  *USART1_CR1 &= ~(1u << 10); /* 0: Parity control disabled  */
-  /* STOP: STOP bits  */
-  *USART1_CR2 &= ~(0b11u << 12); /* 00: 1 Stop bit  */
-  /* Clock frequency: 25MHz
-   * Desired baud rate: 1.2 KBps
-   * USARTDIV = 1302.0625  */
-  *USART1_BRR = (1302u << 4) | 1u; /* mantissa and fraction (/16)  */
-  /* TE: Transmitter enable  */
-  *USART1_CR1 |= (1u << 3); /* 1: Transmitter is enabled  */
-
-  /*  Jump to kernel entry code  --------------------------------------------  */
-
-  /* Clear FAULTMASK  */
-  asm ("cpsie f");
-
-  kentry ();
-}
-
-__attribute__ ((section (".vector_table"), used))
-static unsigned long const vector_table[] = {
-  (unsigned long) &_sram_end,
-  (unsigned long) reset_handler,
-};
diff --git a/led.c b/led.c
new file mode 100644 (file)
index 0000000..6627535
--- /dev/null
+++ b/led.c
@@ -0,0 +1,33 @@
+#include "led.h"
+#include "stm32f411.h"
+
+void
+led_init (void)
+{
+  /* GPIOCEN: IO port C clock enable  */
+  *RCC_AHB1ENR |= (1u << 2); /* 1: IO port C clock enabled  */
+  /* MODERy[1:0]: Port x configuration bits (y = 0..15)  */
+  *GPIOC_MODER &= ~(0b11u << 26); /* Clear PC13 bits  */
+  *GPIOC_MODER |= (1u << 26); /* 01: General purpose output mode  */
+
+  /* PC13: 0 = LED on
+   *       1 = LED off  */
+}
+
+void
+led_on (void)
+{
+  *GPIOC_ODR &= ~(1u << 13);
+}
+
+void
+led_off (void)
+{
+  *GPIOC_ODR |= (1u << 13);
+}
+
+void
+led_toggle (void)
+{
+  *GPIOC_ODR ^= (1u << 13);
+}
diff --git a/led.h b/led.h
new file mode 100644 (file)
index 0000000..5f02ce7
--- /dev/null
+++ b/led.h
@@ -0,0 +1,9 @@
+#ifndef _LED_H_
+#define _LED_H_
+
+void led_init (void);
+void led_on (void);
+void led_off (void);
+void led_toggle (void);
+
+#endif /* _LED_H_  */
diff --git a/sysclk.c b/sysclk.c
new file mode 100644 (file)
index 0000000..a106774
--- /dev/null
+++ b/sysclk.c
@@ -0,0 +1,25 @@
+#include "sysclk.h"
+#include "stm32f411.h"
+
+void
+sysclk_init (void)
+{
+  /* HSEBYP: HSE clock bypass  */
+  *RCC_CR &= ~(1u << 18); /* 0: HSE oscillator not bypassed  */
+
+  /* HSEON: HSE clock enable  */
+  *RCC_CR |= (1u << 16); /* 1: HSE oscillator ON  */
+
+  /* HSERDY: HSE clock ready flag  */
+  while (!(*RCC_CR & (1u << 17))); /* 0: HSE oscillator not ready  */
+
+  /* SW: System clock switch  */
+  *RCC_CFGR &= ~(0b11u); /* Clear SW bits  */
+  *RCC_CFGR |= (0b01u); /* 01: HSE oscillator selected as system clock  */
+
+  /* SWS: System clock switch status  */
+  while ((*RCC_CFGR & (0b11u << 2)) != (0b01u << 2)); /* 01: HSE oscillator used
+                                                         as the system clock  */
+  /* HSION: Internal high-speed clock enable  */
+  *RCC_CR &= ~(1u); /* 0: HSI oscillator OFF  */
+}
diff --git a/sysclk.h b/sysclk.h
new file mode 100644 (file)
index 0000000..b02ae6a
--- /dev/null
+++ b/sysclk.h
@@ -0,0 +1,6 @@
+#ifndef _SYSCLK_H_
+#define _SYSCLK_H_
+
+void sysclk_init (void);
+
+#endif /* _SYSCLK_H_  */
diff --git a/uart.c b/uart.c
new file mode 100644 (file)
index 0000000..7174979
--- /dev/null
+++ b/uart.c
@@ -0,0 +1,80 @@
+#include "uart.h"
+#include "stm32f411.h"
+
+/* Wait for data to be transferred into the shift register.  */
+static void
+busywait_txe (void)
+{
+  /* TXE: Transmit data register empty  */
+  while (!(*USART1_SR & (1u << 7))); /* 0: Data is not transferred to the shift
+                                        register  */
+}
+
+/* Wait for transmission of the last frame.  */
+static void
+busywait_tc (void)
+{
+  /* TC: Transmission complete  */
+  while (!(*USART1_SR & (1u << 6))); /* 0: Transmission is not complete  */
+}
+
+static void
+tx (char c)
+{
+  /* DR[8:0]: Data value  */
+  *USART1_DR = c;
+}
+
+void
+uart_init (void)
+{
+  /* GPIOAEN: IO port A clock enable  */
+  *RCC_AHB1ENR |= (1u); /* 1: IO port A clock enabled  */
+
+  /* MODERy[1:0]: Port x configuration bits (y = 0..15)  */
+  *GPIOA_MODER &= ~(0b1111u << 18); /* Clear PA9 and PA10 bits  */
+  *GPIOA_MODER |= (0b1010u << 18); /* 10: Alternate function mode  */
+
+  /* AFRHy: Alternate function selection for port x bit y (y = 8..15)  */
+  *GPIOA_AFRH &= ~(0b11111111u << 4); /* Clear PA9 and PA10 bits  */
+  *GPIOA_AFRH |= (0b01110111u << 4); /* 0111: AF7  */
+
+  /* PA9: USART1_TX
+   * PA10: USART1_RX  */
+
+  /* USART1EN: USART1 clock enable  */
+  *RCC_APB2ENR |= (1u << 4); /* 1: USART1 clock enabled  */
+
+  /* UE: USART enable  */
+  *USART1_CR1 |= (1u << 13); /* 1: USART enable  */
+
+  /* M: Word length  */
+  *USART1_CR1 &= ~(1u << 12); /* 0: 1 Start bit, 8 Data bits, n Stop bit  */
+
+  /* PCE: Parity control enable  */
+  *USART1_CR1 &= ~(1u << 10); /* 0: Parity control disabled  */
+
+  /* STOP: STOP bits  */
+  *USART1_CR2 &= ~(0b11u << 12); /* 00: 1 Stop bit  */
+
+  /* Clock frequency: 25MHz
+   * Desired baud rate: 1.2 KBps */
+
+  /* Mantissa and fraction (/16)  */
+  *USART1_BRR = (1302u << 4) | 1u; /* USARTDIV = 1302.0625  */
+
+  /* TE: Transmitter enable  */
+  *USART1_CR1 |= (1u << 3); /* 1: Transmitter is enabled  */
+}
+
+void
+kputs_busytc (const char *str)
+{
+  while (*str)
+  {
+    busywait_txe ();
+    tx (*(str++));
+  }
+
+  busywait_tc ();
+}
diff --git a/uart.h b/uart.h
new file mode 100644 (file)
index 0000000..ee16d4c
--- /dev/null
+++ b/uart.h
@@ -0,0 +1,9 @@
+#ifndef _UART_H_
+#define _UART_H_
+
+void uart_init (void);
+
+/* Busy waiting, wait for Transmission Complete (TC).  */
+void kputs_busytc (const char *str);
+
+#endif /* _UART_H_  */