ULP global variables

User avatar
ESP_krzychb
Posts: 400
Joined: Sat Oct 01, 2016 9:05 am
Contact:

Re: ULP global variables

Postby ESP_krzychb » Wed Oct 04, 2017 6:35 pm

@urbanze,

I have verified this issue in native esp-idf environment and see @WiFive nailed it down already :D
It disappears after removing extraneous "extern uint32_t ulp_x = 1;" from the main c program code.
It shows up if I put "extern uint32_t ulp_x = 1;" back.

Complete code that works is below:

ulp:

Code: Select all

	.bss

	.global x
x:	.long 0

	.text
	.global entry
entry:

	move r1, x    // Get adress of x
	ld r0, r1, 0  // Read x in r0
	add r0, r0, 1 // Increment x
	st r0, r1, 0  // Save the x in memory

	halt
ulp_main.c:

Code: Select all

#include <stdio.h>
#include "soc/rtc_cntl_reg.h"
#include "esp_sleep.h"
#include "esp32/ulp.h"
#include "ulp_main.h"

extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[]   asm("_binary_ulp_main_bin_end");

void app_main()
{
    ESP_ERROR_CHECK(ulp_load_binary(0, ulp_main_bin_start,
            (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t)));

    ulp_x = 1;

    printf("Toggle counter %d\n", ulp_x & UINT16_MAX);

    ESP_ERROR_CHECK( ulp_run((&ulp_entry - RTC_SLOW_MEM) / sizeof(uint32_t)));

    printf("Print something to kill some time...\n");
    printf("Toggle counter %d\n", ulp_x & UINT16_MAX);

	esp_deep_sleep_start();
}
Output:

Code: Select all

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x16 (SPI_FAST_FLASH_BOOT)
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x16 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0010,len:4
load:0x3fff0014,len:3188
load:0x40078000,len:0
load:0x40078000,len:11056
entry 0x40078c10
Toggle counter 1
Print something to kill some time...
Toggle counter 2
I do not have Arduino but can try to set it up if you provide installation details.

User avatar
urbanze
Posts: 301
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: ULP global variables

Postby urbanze » Wed Oct 04, 2017 7:11 pm

krzychb wrote:@urbanze,

I have verified this issue in native esp-idf environment and see @WiFive nailed it down already :D
It disappears after removing extraneous "extern uint32_t ulp_x = 1;" from the main c program code.
It shows up if I put "extern uint32_t ulp_x = 1;" back.

Complete code that works is below:

ulp:

Code: Select all

	.bss

	.global x
x:	.long 0

	.text
	.global entry
entry:

	move r1, x    // Get adress of x
	ld r0, r1, 0  // Read x in r0
	add r0, r0, 1 // Increment x
	st r0, r1, 0  // Save the x in memory

	halt
ulp_main.c:

Code: Select all

#include <stdio.h>
#include "soc/rtc_cntl_reg.h"
#include "esp_sleep.h"
#include "esp32/ulp.h"
#include "ulp_main.h"

extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[]   asm("_binary_ulp_main_bin_end");

void app_main()
{
    ESP_ERROR_CHECK(ulp_load_binary(0, ulp_main_bin_start,
            (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t)));

    ulp_x = 1;

    printf("Toggle counter %d\n", ulp_x & UINT16_MAX);

    ESP_ERROR_CHECK( ulp_run((&ulp_entry - RTC_SLOW_MEM) / sizeof(uint32_t)));

    printf("Print something to kill some time...\n");
    printf("Toggle counter %d\n", ulp_x & UINT16_MAX);

	esp_deep_sleep_start();
}
Output:

Code: Select all

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x16 (SPI_FAST_FLASH_BOOT)
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x16 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0010,len:4
load:0x3fff0014,len:3188
load:0x40078000,len:0
load:0x40078000,len:11056
entry 0x40078c10
Toggle counter 1
Print something to kill some time...
Toggle counter 2
I do not have Arduino but can try to set it up if you provide installation details.
This worked, I use esp-idf with arduino component then work 99% equals, but not as expected.

1-) After ulp_run (), we increase the value of X by +1 and close with HALT, correct?!. When I apply a delay (100) after ulp_run (), the value of x is 66. So I switched from 100 to 50mS and the value went to 33mS. Why?

EDIT: I read the doc of "ULP flow" and understand now. Please, anwser question 2 :D


2-) The assembly code only worked with .bss and .text (removing them, not working). What they do? Why and when should I put them?

I did not see them saying anything about them. If there really is not and that is why it did not work, you should put information about it in github.

EDIT: I "googled" and see: .bss is section to declare variables, but why github dont tell about this?


3-) What is default clock of ULP? How change?

EDIT: Here, default clock is 8MHz. How change?

Image of code and output:
Image

User avatar
ESP_krzychb
Posts: 400
Joined: Sat Oct 01, 2016 9:05 am
Contact:

Re: ULP global variables

Postby ESP_krzychb » Thu Oct 05, 2017 8:49 pm

Hi urbanze,

I am happy to see that you have answered most of the questions already!
urbanze wrote:2-) The assembly code only worked with .bss and .text (removing them, not working). What they do? Why and when should I put them?

I did not see them saying anything about them. If there really is not and that is why it did not work, you should put information about it in github.

EDIT: I "googled" and see: .bss is section to declare variables, but why github dont tell about this?
There is some explanation of ".bss and .text " provided in:
* https://github.com/espressif/esp-idf/bl ... _cnt.S#L29
* https://github.com/espressif/esp-idf/bl ... _cnt.S#L65

I agree it is worth adding it directly in documentation, e.g. in https://esp-idf.readthedocs.io/en/lates ... g-ulp-code

urbanze wrote:3-) What is default clock of ULP? How change?

EDIT: Here, default clock is 8MHz. How change?
ESP-IDF is not prepared and has not been tested for changing this clock. You can certainly experiment, but do not be surprised that some functionality gets broken and you will be left on your own to figure out why.

If you find this challenging then this is great. First check ESP32 Technical Reference Manual, search for figure "RTC Low-Power Clocks" to understand what else depends on this clock. Then you can start experimenting with https://github.com/espressif/esp-idf/bl ... #L214-L218. To go further explore what else you can tweak in RTC_CNTL_CLK_CONF_REG. Good luck :D

User avatar
urbanze
Posts: 301
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: ULP global variables

Postby urbanze » Fri Oct 06, 2017 5:59 pm

krzychb wrote:Hi urbanze,

I am happy to see that you have answered most of the questions already!
urbanze wrote:2-) The assembly code only worked with .bss and .text (removing them, not working). What they do? Why and when should I put them?

I did not see them saying anything about them. If there really is not and that is why it did not work, you should put information about it in github.

EDIT: I "googled" and see: .bss is section to declare variables, but why github dont tell about this?
There is some explanation of ".bss and .text " provided in:
* https://github.com/espressif/esp-idf/bl ... _cnt.S#L29
* https://github.com/espressif/esp-idf/bl ... _cnt.S#L65

I agree it is worth adding it directly in documentation, e.g. in https://esp-idf.readthedocs.io/en/lates ... g-ulp-code

urbanze wrote:3-) What is default clock of ULP? How change?

EDIT: Here, default clock is 8MHz. How change?
ESP-IDF is not prepared and has not been tested for changing this clock. You can certainly experiment, but do not be surprised that some functionality gets broken and you will be left on your own to figure out why.

If you find this challenging then this is great. First check ESP32 Technical Reference Manual, search for figure "RTC Low-Power Clocks" to understand what else depends on this clock. Then you can start experimenting with https://github.com/espressif/esp-idf/bl ... #L214-L218. To go further explore what else you can tweak in RTC_CNTL_CLK_CONF_REG. Good luck :D

I'm trying to do functions, but I'm having trouble getting back to where the function was called. My searches have reached the use of CALL and RET, but they do not work in the ULP. How can I do to after JUMP, return back and continue the code normally?

I was able to do it another way, but I wanted it to return to the place of call just like the other languages they do commonly.

like this:

Code: Select all

int main()
{
	add()
	//do anyt.
}

void add()
{
	//do anyt.
}

Error with call/ret:

https://i.imgur.com/tCs7C1A.png
Image

User avatar
urbanze
Posts: 301
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: ULP global variables

Postby urbanze » Fri Oct 06, 2017 6:10 pm

krzychb wrote:Hi urbanze,

I am happy to see that you have answered most of the questions already!
urbanze wrote:2-) The assembly code only worked with .bss and .text (removing them, not working). What they do? Why and when should I put them?

I did not see them saying anything about them. If there really is not and that is why it did not work, you should put information about it in github.

EDIT: I "googled" and see: .bss is section to declare variables, but why github dont tell about this?
There is some explanation of ".bss and .text " provided in:
* https://github.com/espressif/esp-idf/bl ... _cnt.S#L29
* https://github.com/espressif/esp-idf/bl ... _cnt.S#L65

I agree it is worth adding it directly in documentation, e.g. in https://esp-idf.readthedocs.io/en/lates ... g-ulp-code

urbanze wrote:3-) What is default clock of ULP? How change?

EDIT: Here, default clock is 8MHz. How change?
ESP-IDF is not prepared and has not been tested for changing this clock. You can certainly experiment, but do not be surprised that some functionality gets broken and you will be left on your own to figure out why.

If you find this challenging then this is great. First check ESP32 Technical Reference Manual, search for figure "RTC Low-Power Clocks" to understand what else depends on this clock. Then you can start experimenting with https://github.com/espressif/esp-idf/bl ... #L214-L218. To go further explore what else you can tweak in RTC_CNTL_CLK_CONF_REG. Good luck :D

I'm trying to do functions, but I'm having trouble getting back to where the function was called. My searches have reached the use of CALL and RET, but they do not work in the ULP. How can I do to after JUMP, return back and continue the code normally?

I would like to do this without using one of the precious 4 registers.
I was able to do it another way, but I wanted it to return to the place of call just like the other languages they do commonly.

like this:

Code: Select all

int main()
{
	add()
	//do anyt.
}

void add()
{
	//do anyt.
}

Error with call/ret:

https://i.imgur.com/tCs7C1A.png
Image[/quote]

tomtor
Posts: 22
Joined: Thu May 11, 2017 6:15 am

Re: ULP global variables

Postby tomtor » Sat Oct 07, 2017 12:56 pm


User avatar
urbanze
Posts: 301
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: ULP global variables

Postby urbanze » Mon Oct 09, 2017 4:19 am

Hi tomtor! Thanks for reply.

You know how do this without use r0-r3 registers? I can do simples static functions with .macro, but I really want call/ret or similars without precious r0,r1,r2,r3 regs. :?

tomtor
Posts: 22
Joined: Thu May 11, 2017 6:15 am

Re: ULP global variables

Postby tomtor » Mon Oct 09, 2017 6:46 am

urbanze wrote:
Hi tomtor! Thanks for reply.

You know how do this without use r0-r3 registers? I can do simples static functions with .macro, but I really want call/ret or similars without precious r0,r1,r2,r3 regs. :?
Not sure what you want to accomplish.

You can either pass arguments to functions in registers or you push them on the stack. Either way you have to consider the registers as scratch registers because the called function may use and overwrite them. So you have to save the registers in the caller or on the called function.

A standard way is to reserve space for local function variables on the stack and access them by using an offset to the stack pointer, e.g.

Edit: fix bug

Code: Select all

Sub r3,r3,3 // reserve space for 3 local 4 byte vars
Move r0,0 
St r0,r3,12 // set var 3 to 0

User avatar
urbanze
Posts: 301
Joined: Sat Jun 10, 2017 9:55 pm
Location: Brazil

Re: ULP global variables

Postby urbanze » Tue Oct 10, 2017 1:40 pm

tomtor wrote:
urbanze wrote:
Hi tomtor! Thanks for reply.

You know how do this without use r0-r3 registers? I can do simples static functions with .macro, but I really want call/ret or similars without precious r0,r1,r2,r3 regs. :?
Not sure what you want to accomplish.

You can either pass arguments to functions in registers or you push them on the stack. Either way you have to consider the registers as scratch registers because the called function may use and overwrite them. So you have to save the registers in the caller or on the called function.

A standard way is to reserve space for local function variables on the stack and access them by using an offset to the stack pointer, e.g.

Edit: fix bug

Code: Select all

Sub r3,r3,3 // reserve space for 3 local 4 byte vars
Move r0,0 
St r0,r3,12 // set var 3 to 0
I'm trying to create local numeric variables (to be able to use in macros), but all the methods I've tried from various sites do not compile!

I have already tried declaring local labels for macros:

\1:
&1:
$ 1:
LOCAL 1:

etc. With this, I would use jump 1b to go to label "1" before the jump.

None worked. How can I define these "dynamic labels" for use in macros? I need to call the macro several times.
If I use symbolic labels (like: "abc:"), assembler says: "label already defined".


Reference with dynamic labels:
https://sourceware.org/binutils/docs-2. ... mbol-Names

Error with jump 1b: https://i.imgur.com/EB2qDbv.png
Image
PS: I changed "1:" by "4:" and "32bit adress error" disapper, but "b" error still.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: ULP global variables

Postby WiFive » Tue Oct 10, 2017 9:01 pm


Who is online

Users browsing this forum: No registered users and 83 guests