2024-02-25 04:37 AM
Hi,
I am working on FreeRTOS, I came to a section where I need to enable CYCNT register of Arm-Cortex. In order to achieve that, I understand I must set DWT_CTRL registers enable bit that is at 0xE0001000 address. All I dont understand is why a define like below (line#1) is used to assign the value of the register to a macro (DWT_CTRL) and modified at line#34 as below?
Could you pls point me in the right direction ?
#define DWT_CTRL *((volatile uint32_t*)0xE0001000)
int main(void)
{
/* USER CODE BEGIN 1 */
TaskHandle_t task1_handle;
TaskHandle_t task2_handle;
BaseType_t status;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
//Enable the CYCCNT
DWT_CTRL |= (1<<0);
Solved! Go to Solution.
2024-02-25 05:48 AM
(volatile uint32_t *) creates a pointer to a 32-bit memory location
*(volatile uint32_t *) accesses that location
2024-02-25 05:04 AM
Probably line 34 was copypasted from some other project, not based on ST Cube library. This required a definition of DWT_CTRL, which has been copypasted too. It's only matter of taste to define this register as a "variable" or as a struct field referenced by pointer.
2024-02-25 05:07 AM
Thank you.
I am adding RTOS into my project manually rather than using STM32 CUBE IDE Middleware FREE RTOS option. You are right that those lines are copied from other project. What I didnt understand is that what exactly (volatile uint32_t *) does ?
My interpretation is that, the address (0xE0001000) is being a pointer, by adding (volatile uint32_t*) in front of it.
2024-02-25 05:46 AM
This is C language stuff. It's casting the address within the Cortex's address space where the register resides.
volatile because it's not "memory" but a register within the core/peripheral, and all bits may not be writable, or have special logic / sequence actions.
It was done this way to limit the need for external libraries and include files to illustrate the CYCCNT works. ie can be described in 10 lines rather than requiring specific includes, installations, etc.
Perhaps can use DWT->CTRL and DWT->CYCCNT where libraries, structures and addresses have been established.
2024-02-25 05:48 AM
(volatile uint32_t *) creates a pointer to a 32-bit memory location
*(volatile uint32_t *) accesses that location
2024-02-25 06:12 AM
> *(volatile uint32_t *) accesses that location
This creates a L-value from the pointer target as it is used on the left size of expression. Operator |= reads the (R)value of the target, then makes assignment to the target. C++ reference is a clearer way to express this: volatile uint32_t &DWT_CTRL = *((volatile uint32_t*)0xE0001000);