Add a counter for the task

As far as I know, the current task has a single execution function void lv_task_once(lv_task_t * task);.

/**
 * Descriptor of a lv_task
 */
typedef struct _lv_task_t
{
    uint32_t period; /**< How often the task should run */
    uint32_t last_run; /**< Last time the task ran */
    lv_task_cb_t task_cb; /**< Task function */

    void * user_data; /**< Custom user data */

    uint8_t prio : 3; /**< Task priority */
    uint8_t once : 1; /**< 1: one shot task */
} lv_task_t;

/**
 * Delete the lv_task after one call
 * @param task pointer to a lv_task.
 */
void lv_task_once(lv_task_t * task);

But sometimes we need to control the times of tasks to be execute .
Maybe more than once.

Therefore, I think it can be simply modified to achieve the purpose.

/**
 * Descriptor of a lv_task
 */
typedef struct _lv_task_t
{
    uint32_t period; /**< How often the task should run */
    uint32_t last_run; /**< Last time the task ran */
    lv_task_cb_t task_cb; /**< Task function */

    void * user_data; /**< Custom user data */

    uint8_t prio : 3; /**< Task priority */
    //uint8_t once : 1; /**< 1: one shot task */
    int32_t time; /**< 1: Task times;  -1 : infinity;  0 : stop ;  n>0: residual times */
} lv_task_t;
1 Like

Couldn’t you just enable and disable the task within your application? You could call lv_task_set_prio(task, LV_TASK_PRIO_OFF) after it’s been run several times. I think that would be simpler.

Has this been solved? I am dealing with a similar situation where I want to stop a task after x times instead of only 1.

Imagine that I press a button and that button activates a task. After that I am not doing anything else, the only code running is the task code and I really want it to stop after 10 times. Since I can’t, from inside the function, to tell it to stop, I can’t call lv_task_set_prio(task, LV_TASK_PRIO_OFF).

Any workaround? Thanks! (btw I am using micropython).

So never mind what I right above, if you are using a task with lambdas you can actually pass your task handler as an argument and use it from inside the CB function. Then inside the CB function you can call lv.task_set_prio(task, lv.TASK_PRIO.OFF). The downside is that you need to have a global tracking the number of times that your function was called and remember to reset the global if you interrupt the task somewhere else (or to reset it to 0 before you start the task)
An approach like @ShenRen suggested would be cleaner and more user friendly. But I understand if this is not a priority.

Example:

global CALLS
CALLS = 0
task = lv.task_create(lambda task: your_cb_function(task, ...), 500, lv.TASK_PRIO.HIGH, None)
   
def your_cb_function(task,...):
    global CALLS
    ....
    if CALLS == 10:
        lv.task_set_prio(task, lv.TASK_PRIO.OFF)
        CALLS = 0
    else:
        CALLS+=1

I think adding uint32_t cnt wouldn’t cause notable increase in memory usage and really could be useful in some cases. @embeddedt what do you think?

I agree. We should keep a stub of the lv_task_once API around in lv_api_map.h for compatibility though.

I agree. @Tiago_Almeida or @embeddedt are you interested in adding it?

I can add it.

I’ve implemented it here: https://github.com/littlevgl/lvgl/pull/1452

2 Likes