• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

テスト用のあれこれ共用フォルダ


Commit MetaInfo

修訂a7de957107e3b23ebb1b8a3954d2761728d1bbea (tree)
時間2018-09-23 16:21:31
作者takemasa <suikan@user...>
Commitertakemasa

Log Message

The uart.* are copied to the debuggeruart.*.

The current uart.* usage in the logger is not allowed to use the SYSLOG.
Then, the debuggeruart.* was copied from the uart.* and left as dedicated
to the logging.

The uart.* will be modified to implement the advance usage.

Change Summary

差異

--- /dev/null
+++ b/stm32_development/murasaki/murasaki/debuggeruart.cpp
@@ -0,0 +1,194 @@
1+/*
2+ * debuggerart.cpp
3+ *
4+ * Created on: 2018/09/23
5+ * Author: takemasa
6+ */
7+
8+#include "debuggeruart.hpp"
9+#include "murasaki_defs.hpp"
10+#include "murasaki_assert.hpp"
11+
12+// Check if CubeMX generates UART module
13+#ifdef HAL_UART_MODULE_ENABLED
14+
15+
16+namespace murasaki {
17+
18+DebuggerUart::DebuggerUart(UART_HandleTypeDef * const uart)
19+ : peripheral_(uart),
20+ tx_sync_(new murasaki::Synchronizer),
21+ rx_sync_(new murasaki::Synchronizer),
22+ tx_critical_section_( new murasaki::CriticalSection),
23+ rx_critical_section_(new murasaki::CriticalSection)
24+{
25+ // Setup internal variable with given uart structure.
26+
27+ MURASAKI_ASSERT(nullptr != uart)
28+ MURASAKI_ASSERT(nullptr != tx_sync_)
29+ MURASAKI_ASSERT(nullptr != rx_sync_)
30+ MURASAKI_ASSERT(nullptr != tx_critical_section_)
31+ MURASAKI_ASSERT(nullptr != rx_critical_section_)
32+
33+}
34+
35+DebuggerUart::~DebuggerUart()
36+{
37+
38+ if (nullptr != tx_sync_)
39+ delete tx_sync_;
40+
41+ if (nullptr != rx_sync_)
42+ delete rx_sync_;
43+
44+ if (nullptr != tx_critical_section_)
45+ delete tx_critical_section_;
46+
47+ if (nullptr != tx_critical_section_)
48+ delete rx_critical_section_;
49+}
50+
51+void DebuggerUart::SetHardwareFlowControl(UartHardwareFlowControl control)
52+{
53+ // stop UART activity. This is required by UART HAL specification.
54+ int result = HAL_UART_DeInit(peripheral_);
55+ MURASAKI_ASSERT(result == HAL_OK);
56+
57+
58+ // Change the Hardware flow control
59+ switch (control) {
60+ case kuhfcCts : // Control CTS only ( Flow control on TX )
61+ peripheral_->Init.HwFlowCtl = UART_HWCONTROL_CTS;
62+ break;
63+ case kuhfcRts : // Control RTS only ( Flow control on RX )
64+ peripheral_->Init.HwFlowCtl = UART_HWCONTROL_RTS;
65+ break;
66+ case kuhfcCtsRts : // Control CTS and RTS ( Flow control on TX and RX )
67+ peripheral_->Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
68+ break;
69+ default: // Nor hardware flow control.
70+ peripheral_->Init.HwFlowCtl = UART_HWCONTROL_NONE;
71+ break;
72+
73+ }
74+ // restart UART acitivty.
75+ result = HAL_UART_Init(peripheral_);
76+ MURASAKI_ASSERT(result == HAL_OK);
77+}
78+
79+bool DebuggerUart::Transmit(const uint8_t * data, unsigned int size,
80+ WaitMilliSeconds timeout_ms)
81+{
82+ bool ret_val;
83+
84+ MURASAKI_ASSERT(nullptr != data)
85+ MURASAKI_ASSERT(65536 > size);
86+
87+ // make this methold re-entrant in task context.
88+ tx_critical_section_->Enter();
89+ {
90+ // Keep coherency between the L2 and cache before DMA
91+ murasaki::InvalidateDataCacheByAddress(const_cast<uint8_t *>(data),
92+ size);
93+
94+ HAL_StatusTypeDef status = HAL_UART_Transmit_DMA(peripheral_,
95+ const_cast<uint8_t *>(data), size);
96+ MURASAKI_ASSERT(HAL_OK == status);
97+
98+ ret_val = tx_sync_->Wait(timeout_ms);
99+ }
100+ tx_critical_section_->Leave();
101+
102+ return ret_val; // true if Semaphore taken without timeout ( mean, transfered without timeout )
103+}
104+
105+bool DebuggerUart::TransmitCompleteCallback(void* const ptr)
106+{
107+ MURASAKI_ASSERT(nullptr != ptr)
108+
109+ if (ptr == peripheral_) {
110+ tx_sync_->Release();
111+ return true;
112+ }
113+ else {
114+ return false;
115+ }
116+}
117+
118+bool DebuggerUart::Receive(uint8_t * data, unsigned int size, WaitMilliSeconds timeout_ms)
119+{
120+ bool ret_val;
121+
122+ MURASAKI_ASSERT(nullptr != data);
123+ MURASAKI_ASSERT(65536 > size);
124+
125+ // make this methold re-entrant in task context.
126+ rx_critical_section_->Enter();
127+ {
128+ // Keep coherency between the L2 and cache before DMA
129+ murasaki::InvalidateDataCacheByAddress(data, size);
130+
131+ HAL_StatusTypeDef status = HAL_UART_Receive_DMA(peripheral_, data, size);
132+ MURASAKI_ASSERT(HAL_OK == status);
133+
134+ ret_val = rx_sync_->Wait(timeout_ms);
135+ }
136+ rx_critical_section_->Leave();
137+
138+ return ret_val; // true if Semaphore taken without timeout ( mean, transfered without timeout )
139+}
140+
141+void DebuggerUart::SetSpeed(unsigned int baud_rate)
142+{
143+ // stop UART activity. This is required by UART HAL specification.
144+ int result = HAL_UART_DeInit(peripheral_);
145+ MURASAKI_ASSERT(result == HAL_OK);
146+
147+ // Change the Speed
148+ peripheral_->Init.BaudRate = baud_rate;
149+
150+ // restart UART acitivty.
151+ result = HAL_UART_Init(peripheral_);
152+ MURASAKI_ASSERT(result == HAL_OK);
153+
154+}
155+
156+bool DebuggerUart::ReceiveCompleteCallback(void* const ptr)
157+{
158+ MURASAKI_ASSERT(nullptr != ptr)
159+
160+ if (peripheral_ == ptr) {
161+ rx_sync_->Release();
162+ return true;
163+ }
164+ else {
165+ return false;
166+ }
167+}
168+
169+bool DebuggerUart::HandleError(void* const ptr)
170+{
171+ MURASAKI_ASSERT(nullptr != ptr)
172+
173+ if (peripheral_ == ptr) {
174+ // Check error, and print if exist.
175+ MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_UART_ERROR_DMA);
176+ MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_UART_ERROR_PE);
177+ MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_UART_ERROR_NE);
178+ MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_UART_ERROR_FE);
179+ MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_UART_ERROR_ORE);
180+ MURASAKI_PRINT_ERROR(peripheral_->ErrorCode & HAL_UART_ERROR_DMA);
181+ return true; // report the ptr matched
182+ }
183+ else {
184+ return false; // report the ptr doesn't match
185+ }
186+}
187+
188+void* DebuggerUart::GetPeripheralHandle() {
189+ return peripheral_;
190+}
191+
192+} /* namespace platform */
193+
194+#endif // HAL_UART_MODULE_ENABLED
--- /dev/null
+++ b/stm32_development/murasaki/murasaki/debuggeruart.hpp
@@ -0,0 +1,207 @@
1+/**
2+ * \file debuggeruart.hpp
3+ *
4+ * \date 2018/09/23
5+ * \author takemasa
6+ * @brief UART. Thread safe and blocking IO
7+ */
8+
9+#ifndef DEBUGGER_UART_HPP_
10+#define DEBUGGER_UART_HPP_
11+
12+#include <synchronizer.hpp>
13+#include "abstractuart.hpp"
14+#include "criticalsection.hpp"
15+
16+// Check if CubeMX generates UART module
17+#ifdef HAL_UART_MODULE_ENABLED
18+
19+namespace murasaki {
20+
21+/**
22+ * \ingroup MURASAKI_GROUP
23+ * \brief Concrete implementation of UART controller. Based on the STM32 HAL DMA Transfer.
24+ * \details
25+ *
26+ * The Uart class is the wrapper of the UART controller. To use the Uart class,
27+ * make an instance with UART_HandleTypeDef * type pointer. For example, to create
28+ * an instance for the UART3 peripheral :
29+ * \code
30+ * my_uart3 = new murasaki::Uart(&huart3);
31+ * \endcode
32+ * Where huart3 is the handle generated by CubeMX for UART3 peripheral. To use this class,
33+ * the UART peripheral have to be configured to use the DMA functionality. The baud rate,
34+ * length and flow control should be configured by the CubeMX.
35+ *
36+ * In addition to the instantiation, we need to prepare an interrupt callback.
37+ * \code
38+ * void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)
39+ * {
40+ * my_uart3->TransmitCompleteCallback(huart);
41+ * }
42+ * \endcode
43+ * Where HAL_UART_TxCpltCallback is a predefined name of the UART interrupt handler.
44+ * This is invoked by system whenever a DMA baed UART transmission is complete.
45+ * Becuase the default function is weakly bound, above definition will overwride the
46+ * default one.
47+ *
48+ * Note that above callback is invoked for any UARTn where n is 1, 2, 3... To avoid the
49+ * confusion, Uart::TransmitCompleteCallback() method chckes whether given parameter
50+ * matches with its UART_HandleTypeDef * pointer ( which was passed to constructor ).
51+ * And only when both matches, the member function execute the interrupt termination process.
52+ *
53+ * As same as Tx, RX needs HAL_UART_TxCpltCallback().
54+ *
55+ * Once the instance and callbacks are correctly prepared, we can use the Tx/Rx member function.
56+ *
57+ * The @ref Uart::Transmit() member function is a blocking function. A programmer can specify the
58+ * timeout by timeout_ms parameter. By default, this parameter is set by kwmsIndefinitely
59+ * which specifes never time out.
60+ *
61+ * The @ref Uart::Receive() member function is a blocking function. A programmer can specify the
62+ * timeout by timeout_ms parameter. By default, this parameter is set by kwmsIndefinitely
63+ * which specifes never time out.
64+ *
65+ * Both methods can be called from only the task context. If these are called in the ISR
66+ * context, the result is unknown.
67+ */
68+class DebuggerUart : public AbstractUart
69+{
70+ public:
71+ /**
72+ * \brief Constructor
73+ * \param uart Pointer to a UART control struct. This device have to be configured to use DMA and interrupt for both Tx and Rx.
74+ * \details
75+ * Store the given uart pointer into the internal variable. This pointer is passed to the STM32 HAL UART functions when needed.
76+ *
77+ */
78+ DebuggerUart(UART_HandleTypeDef * uart);
79+ /**
80+ * \brief Destructor. Delete internal variables.
81+ */
82+ virtual ~DebuggerUart();
83+ /**
84+ * \brief Set the behavior of the hardware flow control
85+ * \param control The control mode.
86+ * \details
87+ * Before calling this method, all transmission and recevie activites have to be finished.
88+ * This is responsibility of the programmer.
89+ *
90+ * Note this method is NOT re-etnrant.
91+ * In other word, this member function can be called from both task and interrupt context.
92+ */
93+ virtual void SetHardwareFlowControl(UartHardwareFlowControl control);
94+ /**
95+ * @brief Set the BAUD rate
96+ * @param baud_rate BAUD rate ( 110, 300,... 57600,... )
97+ * \details
98+ * Before calling this method, all transmission and recevie activites have to be finished.
99+ * This is responsibility of the programmer.
100+ *
101+ * Note this method is NOT re-etnrant.
102+ * In other word, this member function can be called from both task and interrupt context.
103+ */
104+ virtual void SetSpeed(unsigned int baud_rate);
105+
106+ /**
107+ * \brief Transmit raw data through an UART by blocking mode.
108+ * \param data Data buffer to be transmitted.
109+ * \param size The count of the data ( byte ) to be transfered. Must be smaller than 65536
110+ * \param timeout_ms Time out limit by milliseconds.
111+ * \return True if all data transfered completely. False if time out happen.
112+ * \details
113+ * Transmit given data buffer through an UART device.
114+ *
115+ * The transmission mode is blocking. That means, function returns when all data has been transmitted, except timeout.
116+ * Passing \ref murasaki::kwmsIndefinitely to the parameter timeout_ms orders not to return until complete transmission. Other value of
117+ * timeout_ms parameter specifies the time out by millisecond. If time out happen, function returns false. If not happen, it returns true.
118+ *
119+ * This function is exclusive. Internally the function is guarded by mutex. Then this function is thread safe.
120+ * This function is forbiddedn to call from ISR.
121+ */
122+ virtual bool Transmit(const uint8_t * data, unsigned int size,
123+ WaitMilliSeconds timeout_ms = kwmsIndefinitely);
124+ /**
125+ * \brief Receive raw data through an UART by blocking mode.
126+ * \param data Data buffer to place the received data..
127+ * \param count The count of the data ( byte ) to be transfered. Must be smaller than 65536
128+ * \param timeout_ms Time out limit by milliseconds.
129+ * \return True if all data transfered completely. False if time out happen.
130+ * \details
131+ * Receive to given data buffer through an UART device.
132+ *
133+ * The receiving mode is blocking. That means, function returns when specified number of data has been received, except timeout.
134+ * Passing \ref murasaki::kwmsIndefinitely to the parameter timeout_ms orders not to return until complete receiving. Other value of
135+ * timeout_ms parameter specifies the time out by millisecond.
136+ * If time out happen, function returns false. If not happen, it returns true.
137+ *
138+ * This function is exclusive. Internally this function is guarded by mutex. Then this function is thread safe.
139+ * This function is forbiddedn to call from ISR.
140+ */
141+ virtual bool Receive(uint8_t * data, unsigned int count, WaitMilliSeconds timeout_ms = kwmsIndefinitely);
142+ /**
143+ * \brief Call back for entire block transfer completion.
144+ * \param ptr Pointer to UART_HandleTypeDef struct.
145+ * \return true: ptr matches with UART device and handle the call back. false : doesn't match.
146+ * \details
147+ * A call back to notify the end of entire block transfer.
148+ * This is considered as the end of DMA based transmission.
149+ * The context have to be interrupt.
150+ *
151+ * This member function checks whether the given ptr parameter matches its own device, and if matched,
152+ * Release the waiting task and return true. If it doesn't match, just return false.
153+ *
154+ * This method have to be called from HAL_UART_TxCpltCallback(). See STM32F7 HAL manual for detail
155+ */
156+
157+ virtual bool TransmitCompleteCallback(void * const ptr);
158+ /**
159+ * \brief Call back for entire block transfer completion.
160+ * \param ptr Pointer to UART_HandleTypeDef struct.
161+ * \return true: ptr matches with UART device and handle the call back. false : doesn't match.
162+ * \details
163+ * A call back to notify the end of entire block transfer.
164+ * This is considered as the end of DMA based receiving.
165+ * The context have to be interrupt.
166+ *
167+ * This member function checks whether the given ptr parameter matches its own device, and if matched,
168+ * Release the waiting task and return true. If it doesn't match, just return false.
169+ *
170+ * This method have to be called from HAL_UART_RxCpltCallback(). See STM32F7 HAL manual for detail */
171+
172+ virtual bool ReceiveCompleteCallback(void* const ptr);
173+ /**
174+ * @brief Error handling
175+ * @param ptr Pointer to UART_HandleTypeDef struct.
176+ * \return true: ptr matches with UART device and handle the error. false : doesn't match.
177+ * @details
178+ * A handle to print out the error message.
179+ *
180+ * Checks whether handle has error and if there is, print appropriate error. Then return.
181+ */
182+ virtual bool HandleError(void * const ptr);
183+protected:
184+ UART_HandleTypeDef* const peripheral_;
185+
186+ Synchronizer * const tx_sync_;
187+ Synchronizer * const rx_sync_;
188+
189+ CriticalSection * const tx_critical_section_;
190+ CriticalSection * const rx_critical_section_;
191+private:
192+ /**
193+ * @brief Return the Platform dependent device control handle.
194+ * @return Handle of device.
195+ * @details
196+ * The handle is the pointer ( or some ID ) which specify the control data of
197+ * specific device.
198+ */
199+ virtual void * GetPeripheralHandle();
200+
201+};
202+
203+} /* namespace platform */
204+
205+#endif // HAL_UART_MODULE_ENABLED
206+
207+#endif /* DEBUGGER_UART_HPP_ */
--- a/stm32_development/murasaki/murasaki/murasaki.hpp
+++ b/stm32_development/murasaki/murasaki/murasaki.hpp
@@ -37,6 +37,7 @@
3737
3838 // Peripherals
3939 #include "uart.hpp"
40+#include "debuggeruart.hpp"
4041 #include "spimaster.hpp"
4142 #include "spislavespecifier.hpp"
4243 #include "i2cmaster.hpp"
--- a/stm32_development/nucleo-l152re-fujitsubo-test/NUCLEO-L152RE.xml
+++ b/stm32_development/nucleo-l152re-fujitsubo-test/NUCLEO-L152RE.xml
@@ -12,8 +12,8 @@
1212 <targetDefinitions>
1313 <board id="nucleo-l152re">
1414 <name>NUCLEO-L152RE</name>
15- <dbgIF>SWD</dbgIF>
1615 <dbgIF>JTAG</dbgIF>
16+ <dbgIF>SWD</dbgIF>
1717 <dbgDEV>ST-Link</dbgDEV>
1818 <mcuId>stm32l152retx</mcuId>
1919 </board>
--- a/stm32_development/nucleo-l152re-fujitsubo-test/Src/murasaki_platform.cpp
+++ b/stm32_development/nucleo-l152re-fujitsubo-test/Src/murasaki_platform.cpp
@@ -66,11 +66,18 @@ void InitPlatform()
6666 // UART device setting for console interface.
6767 // On Nucleo, the port connected to the USB port of ST-Link is
6868 // referred here.
69- murasaki::platform.uart_console = new murasaki::Uart(&huart2);
69+ murasaki::platform.uart_console = new murasaki::DebuggerUart(&huart2);
7070 // UART is used for logging port.
7171 // At least one logger is needed to run the debugger class.
7272 murasaki::platform.logger = new murasaki::UartLogger(murasaki::platform.uart_console);
7373
74+ // Setting the debugger
75+ murasaki::debugger = new murasaki::Debugger(murasaki::platform.logger);
76+ // Set the debugger as AutoRePrint mode, for the easy operation.
77+ murasaki::debugger->AutoRePrint(); // type any key to show history.
78+
79+
80+
7481 // For demonstration, one GPIO LED port is reserved.
7582 // The port and pin names are defined by CubeMX.
7683
@@ -98,11 +105,6 @@ void InitPlatform()
98105 murasaki::platform.u2_m95010 =
99106 new murasaki::SpiSlaveSpecifier(0, 0, SPI_CS_GPIO_Port, SPI_CS_Pin); // POL=0, PHA=0
100107
101- // Setting the debugger
102- murasaki::debugger = new murasaki::Debugger(murasaki::platform.logger);
103- // Set the debugger as AutoRePrint mode, for the easy operation.
104- murasaki::debugger->AutoRePrint(); // type any key to show history.
105-
106108 }
107109
108110 #define M24128_ADDR 0x50
--- a/stm32_development/nucleo-l152re-fujitsubo-test/nucleo-l152re-fujitsubo-test Debug.cfg
+++ b/stm32_development/nucleo-l152re-fujitsubo-test/nucleo-l152re-fujitsubo-test Debug.cfg
@@ -10,6 +10,7 @@ set WORKAREASIZE 0x8000
1010 transport select "hla_swd"
1111
1212 set CHIPNAME STM32L152RETx
13+set BOARDNAME NUCLEO-L152RE
1314
1415 # Enable debug when in low power modes
1516 set ENABLE_LOW_POWER 1